Updated SSSP algorithm to automatically detect indirect links (if a node uses
different addresses for connections to other nodes).
This commit is contained in:
parent
5a88a27742
commit
f48f8f4fed
2 changed files with 48 additions and 22 deletions
65
src/graph.c
65
src/graph.c
|
@ -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);
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
Loading…
Reference in a new issue