Improve recently seen address cache
[tinc] / src / graph.c
index a774eac..5a7a16a 100644 (file)
 #include "system.h"
 
 #include "connection.h"
-#include "device.h"
 #include "edge.h"
 #include "graph.h"
 #include "list.h"
 #include "logger.h"
-#include "names.h"
 #include "netutl.h"
 #include "node.h"
 #include "protocol.h"
 #include "script.h"
 #include "subnet.h"
-#include "utils.h"
 #include "xalloc.h"
-#include "graph.h"
+#include "address_cache.h"
 
 /* Implementation of Kruskal's algorithm.
    Running time: O(EN)
@@ -68,7 +65,7 @@
 static void mst_kruskal(void) {
        /* Clear MST status on connections */
 
-       for list_each(connection_t, c, connection_list) {
+       for list_each(connection_t, c, &connection_list) {
                c->status.mst = false;
        }
 
@@ -76,13 +73,13 @@ static void mst_kruskal(void) {
 
        /* Clear visited status on nodes */
 
-       for splay_each(node_t, n, node_tree) {
+       for splay_each(node_t, n, &node_tree) {
                n->status.visited = false;
        }
 
        /* Starting point */
 
-       for splay_each(edge_t, e, edge_weight_tree) {
+       for splay_each(edge_t, e, &edge_weight_tree) {
                if(e->from->status.reachable) {
                        e->from->status.visited = true;
                        break;
@@ -93,7 +90,7 @@ static void mst_kruskal(void) {
 
        bool skipped = false;
 
-       for splay_each(edge_t, e, edge_weight_tree) {
+       for splay_each(edge_t, e, &edge_weight_tree) {
                if(!e->reverse || (e->from->status.visited == e->to->status.visited)) {
                        skipped = true;
                        continue;
@@ -114,21 +111,23 @@ static void mst_kruskal(void) {
 
                if(skipped) {
                        skipped = false;
-                       next = edge_weight_tree->head;
+                       next = edge_weight_tree.head;
                }
        }
 }
 
+// Not putting it into header, the outside world doesn't need to know about it.
+extern void sssp_bfs(void);
+
 /* Implementation of a simple breadth-first search algorithm.
    Running time: O(E)
 */
-
-static void sssp_bfs(void) {
+void sssp_bfs(void) {
        list_t *todo_list = list_alloc(NULL);
 
        /* Clear visited status on nodes */
 
-       for splay_each(node_t, n, node_tree) {
+       for splay_each(node_t, n, &node_tree) {
                n->status.visited = false;
                n->status.indirect = true;
                n->distance = -1;
@@ -153,7 +152,7 @@ static void sssp_bfs(void) {
                        abort();
                }
 
-               for splay_each(edge_t, e, n->edge_tree) {       /* "e" is the edge connected to "from" */
+               for splay_each(edge_t, e, &n->edge_tree) {       /* "e" is the edge connected to "from" */
                        if(!e->reverse || e->to == myself) {
                                continue;
                        }
@@ -185,7 +184,7 @@ static void sssp_bfs(void) {
 
                        // Only update nexthop if it doesn't increase the path length
 
-                       if(!e->to->status.visited || (e->to->distance == n->distance + 1 && e->weight >= e->to->prevedge->weight)) {
+                       if(!e->to->status.visited || (e->to->distance == n->distance + 1 && e->weight < e->to->prevedge->weight)) {
                                e->to->nexthop = (n->nexthop == myself) ? e->to : n->nexthop;
                        }
 
@@ -217,7 +216,7 @@ static void check_reachability(void) {
        int became_reachable_count = 0;
        int became_unreachable_count = 0;
 
-       for splay_each(node_t, n, node_tree) {
+       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 = now.tv_sec;
@@ -228,6 +227,14 @@ static void check_reachability(void) {
 
                                if(n != myself) {
                                        became_reachable_count++;
+
+                                       if(n->connection && n->connection->outgoing) {
+                                               if(!n->address_cache) {
+                                                       n->address_cache = open_address_cache(n);
+                                               }
+
+                                               add_recent_address(n->address_cache, &n->connection->address);
+                                       }
                                }
                        } else {
                                logger(DEBUG_TRAFFIC, LOG_DEBUG, "Node %s (%s) became unreachable",
@@ -311,7 +318,7 @@ static void check_reachability(void) {
 }
 
 void graph(void) {
-       subnet_cache_flush();
+       subnet_cache_flush_tables();
        sssp_bfs();
        check_reachability();
        mst_kruskal();