Updated SSSP algorithm to automatically detect indirect links (if a node uses

different addresses for connections to other nodes).
This commit is contained in:
Guus Sliepen 2002-03-19 22:48:25 +00:00
parent 5a88a27742
commit f48f8f4fed
2 changed files with 48 additions and 22 deletions

View file

@ -17,7 +17,7 @@
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: graph.c,v 1.1.2.9 2002/03/12 16:30:15 guus Exp $ $Id: graph.c,v 1.1.2.10 2002/03/19 22:48:25 guus Exp $
*/ */
/* We need to generate two trees from the graph: /* We need to generate two trees from the graph:
@ -151,6 +151,7 @@ void sssp_bfs(void)
node_t *n; node_t *n;
halfconnection_t to_hc, from_hc; halfconnection_t to_hc, from_hc;
avl_tree_t *todo_tree; avl_tree_t *todo_tree;
int indirect;
todo_tree = avl_alloc_tree(NULL, NULL); todo_tree = avl_alloc_tree(NULL, NULL);
@ -160,11 +161,13 @@ void sssp_bfs(void)
{ {
n = (node_t *)node->data; n = (node_t *)node->data;
n->status.visited = 0; n->status.visited = 0;
n->status.indirect = 1;
} }
/* Begin with myself */ /* Begin with myself */
myself->status.visited = 1; myself->status.visited = 1;
myself->status.indirect = 0;
myself->nexthop = myself; myself->nexthop = myself;
myself->via = myself; myself->via = myself;
node = avl_alloc_node(); node = avl_alloc_node();
@ -189,25 +192,47 @@ void sssp_bfs(void)
else else
to_hc = e->from, from_hc = e->to; to_hc = e->from, from_hc = e->to;
if(!to_hc.node->status.visited) /* Situation:
{
to_hc.node->status.visited = 1; /
to_hc.node->nexthop = (n->nexthop == myself) ? to_hc.node : n->nexthop; /
to_hc.node->via = (e->options & OPTION_INDIRECT || n->via != n) ? n->via : to_hc.node; ------(n)from_hc-----to_hc
to_hc.node->options = e->options; \
if(sockaddrcmp(&to_hc.node->address, &to_hc.udpaddress)) \
{
node = avl_unlink(node_udp_tree, to_hc.node); n->address is set to the to_hc.udpaddress of the edge left of n.
to_hc.node->address = to_hc.udpaddress; We are currently examining the edge right of n:
if(to_hc.node->hostname)
free(to_hc.node->hostname); - If from_hc.udpaddress != n->address, then to_hc.node is probably
to_hc.node->hostname = sockaddr2hostname(&to_hc.udpaddress); not reachable for the nodes left of n. We do as if the indirectdata
avl_insert_node(node_udp_tree, node); flag is set on edge e.
} - If edge e provides for better reachability of to_hc.node, update
node = avl_alloc_node(); to_hc.node and (re)add it to the todo_tree to (re)examine the reachability
node->data = to_hc.node; of nodes behind it.
avl_insert_before(todo_tree, from, node); */
}
indirect = n->status.indirect || e->options & OPTION_INDIRECT || ((n != myself) && sockaddrcmp(&n->address, &from_hc.udpaddress));
if(to_hc.node->status.visited && (!to_hc.node->status.indirect || indirect))
continue;
to_hc.node->status.visited = 1;
to_hc.node->status.indirect = indirect;
to_hc.node->nexthop = (n->nexthop == myself) ? to_hc.node : n->nexthop;
to_hc.node->via = indirect ? n->via : to_hc.node;
to_hc.node->options = e->options;
if(sockaddrcmp(&to_hc.node->address, &to_hc.udpaddress))
{
node = avl_unlink(node_udp_tree, to_hc.node);
to_hc.node->address = to_hc.udpaddress;
if(to_hc.node->hostname)
free(to_hc.node->hostname);
to_hc.node->hostname = sockaddr2hostname(&to_hc.udpaddress);
avl_insert_node(node_udp_tree, node);
}
node = avl_alloc_node();
node->data = to_hc.node;
avl_insert_before(todo_tree, from, node);
} }
avl_delete_node(todo_tree, from); avl_delete_node(todo_tree, from);

View file

@ -17,7 +17,7 @@
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: node.h,v 1.1.2.12 2002/02/18 16:25:16 guus Exp $ $Id: node.h,v 1.1.2.13 2002/03/19 22:48:25 guus Exp $
*/ */
#ifndef __TINC_NODE_H__ #ifndef __TINC_NODE_H__
@ -34,7 +34,8 @@ typedef struct node_status_t {
int waitingforkey:1; /* 1 if we already sent out a request */ int waitingforkey:1; /* 1 if we already sent out a request */
int visited:1; /* 1 if this node has been visited by one of the graph algorithms */ int visited:1; /* 1 if this node has been visited by one of the graph algorithms */
int reachable:1; /* 1 if this node is reachable in the graph */ int reachable:1; /* 1 if this node is reachable in the graph */
int unused:27; int indirect:1; /* 1 if this node is not directly reachable by us */
int unused:26;
} node_status_t; } node_status_t;
typedef struct node_t { typedef struct node_t {