X-Git-Url: https://tinc-vpn.org/git/browse?a=blobdiff_plain;f=src%2Fgraph.c;h=e6d70afa3f9742bf9e264dbc04ed6cf915d080b5;hb=6eaefb4dbce240334e35f67d9f3db5d4f44e49c9;hp=2fc3b744c4e13fde81ed1d583f6d3b70df304628;hpb=2077451e07f93edc520cf5bc31815624a2b03fdd;p=tinc diff --git a/src/graph.c b/src/graph.c index 2fc3b744..e6d70afa 100644 --- a/src/graph.c +++ b/src/graph.c @@ -46,7 +46,8 @@ #include "system.h" -#include "avl_tree.h" +#include "splay_tree.h" +#include "config.h" #include "connection.h" #include "device.h" #include "edge.h" @@ -62,9 +63,8 @@ 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; @@ -98,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 */ @@ -140,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; @@ -218,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); @@ -228,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; @@ -260,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; @@ -302,8 +307,43 @@ void sssp_bfs(void) } } -void graph(void) -{ - mst_kruskal(); +/* 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 +*/ + +int dump_graph(struct evbuffer *out) { + splay_node_t *node; + node_t *n; + edge_t *e; + + 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; + 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; + if(evbuffer_add_printf(out, " %s -> %s;\n", + e->from->name, e->to->name) == -1) + return errno; + } + + if(evbuffer_add_printf(out, "}\n") == -1) + return errno; + + return 0; +} + +void graph(void) { sssp_bfs(); + mst_kruskal(); }