X-Git-Url: http://git.meshlink.io/?a=blobdiff_plain;f=src%2Fgraph.c;h=bb55dfdcba1c821d25fcf1f27e4c81fc5478fb7f;hb=3fba80174dbe29bcfe0d121a2a1d2e61be5ee57b;hp=5a0aab0ba7bd04979198492ef7ab3854b251484c;hpb=108b238915c5f58b3d94ab433dc5d04e064c2b11;p=meshlink diff --git a/src/graph.c b/src/graph.c index 5a0aab0b..bb55dfdc 100644 --- a/src/graph.c +++ b/src/graph.c @@ -1,6 +1,6 @@ /* graph.c -- graph algorithms - Copyright (C) 2001-2009 Guus Sliepen , + Copyright (C) 2001-2011 Guus Sliepen , 2001-2005 Ivo Timmermans This program is free software; you can redistribute it and/or modify @@ -49,13 +49,16 @@ #include "connection.h" #include "device.h" #include "edge.h" +#include "graph.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) @@ -111,7 +114,7 @@ void mst_kruskal(void) { Running time: O(N^2) */ -void sssp_dijkstra(void) { +static void sssp_dijkstra(void) { splay_node_t *node, *to; edge_t *e; node_t *n, *m; @@ -181,9 +184,6 @@ void sssp_dijkstra(void) { n->address is set to the e->address of the edge left of n to n. We are currently examining the edge e right of n from n: - - If e->reverse->address != n->address, then e->to is probably - not reachable for the nodes left of n. We do as if the indirectdata - flag is set on edge e. - If edge e provides for better reachability of e->to, update e->to. */ @@ -201,27 +201,8 @@ void sssp_dijkstra(void) { e->to->via = indirect ? n->via : e->to; e->to->options = e->options; - if(sockaddrcmp(&e->to->address, &e->address)) { - node = splay_unlink(node_udp_tree, e->to); - sockaddrfree(&e->to->address); - sockaddrcpy(&e->to->address, &e->address); - - if(e->to->hostname) - free(e->to->hostname); - - e->to->hostname = sockaddr2hostname(&e->to->address); - - if(node) - splay_insert_node(node_udp_tree, node); - - if(e->to->options & OPTION_PMTU_DISCOVERY) { - e->to->mtuprobes = 0; - e->to->minmtu = 0; - e->to->maxmtu = MTU; - if(e->to->status.validkey) - send_mtu_probe(e->to); - } - } + if(e->to->address.sa.sa_family == AF_UNSPEC && e->address.sa.sa_family != AF_UNKNOWN) + update_node_udp(e->to, &e->address); ifdebug(SCARY_THINGS) logger(LOG_DEBUG, " Updating edge %s - %s weight %d distance %d", e->from->name, e->to->name, e->weight, e->to->distance); @@ -284,16 +265,12 @@ void sssp_bfs(void) { n->address is set to the e->address of the edge left of n to n. We are currently examining the edge e right of n from n: - - If e->reverse->address != n->address, then e->to is probably - not reachable for the nodes left of n. We do as if the indirectdata - flag is set on edge e. - If edge e provides for better reachability of e->to, update e->to and (re)add it to the todo_list to (re)examine the reachability of nodes behind it. */ - indirect = n->status.indirect || e->options & OPTION_INDIRECT - || ((n != myself) && sockaddrcmp(&n->address, &e->reverse->address)); + indirect = n->status.indirect || e->options & OPTION_INDIRECT; if(e->to->status.visited && (!e->to->status.indirect || indirect)) @@ -318,7 +295,7 @@ void sssp_bfs(void) { list_free(todo_list); } -void check_reachability() { +static void check_reachability(void) { splay_node_t *node, *next; node_t *n; char *name; @@ -346,13 +323,14 @@ void check_reachability() { /* TODO: only clear status.validkey if node is unreachable? */ n->status.validkey = false; - n->status.waitingforkey = false; + n->last_req_key = 0; n->maxmtu = MTU; n->minmtu = 0; n->mtuprobes = 0; - event_del(&n->mtuevent); + if(timeout_initialized(&n->mtuevent)) + event_del(&n->mtuevent); xasprintf(&envp[0], "NETNAME=%s", netname ? : ""); xasprintf(&envp[1], "DEVICE=%s", device ? : ""); @@ -378,48 +356,17 @@ void check_reachability() { free(envp[i]); subnet_update(n, NULL, n->status.reachable); - } - } -} - -/* 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(!n->status.reachable) + update_node_udp(n, NULL); + else if(n->connection) + send_ans_key(n); + } } - - if(evbuffer_add_printf(out, "}\n") == -1) - return errno; - - return 0; } void graph(void) { - subnet_cache_flush(); + subnet_cache_flush(); sssp_dijkstra(); check_reachability(); mst_kruskal();