- while(todo_list->head) {
- n = NULL;
- nnode = NULL;
-
- /* Select node from todo_list with smallest distance */
-
- for(lnode = todo_list->head; lnode; lnode = lnode->next) {
- m = lnode->data;
- if(!n || m->status.indirect < n->status.indirect || m->distance < n->distance) {
- n = m;
- nnode = lnode;
- }
- }
-
- /* Mark this node as visited and remove it from the todo_list */
-
- n->status.visited = true;
- list_unlink_node(todo_list, nnode);
-
- /* Update distance of neighbours and add them to the todo_list */
-
- for(to = n->edge_tree->head; to; to = to->next) { /* "to" is the edge connected to "from" */
- e = to->data;
-
- if(e->to->status.visited || !e->reverse)
- continue;
-
- /* Situation:
-
- /
- /
- ----->(n)---e-->(e->to)
- \
- \
-
- Where e is an edge, (n) and (e->to) are nodes.
- 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 edge e provides for better reachability of e->to, update e->to.
- */
-
- if(e->to->distance < 0)
- list_insert_tail(todo_list, e->to);
-
- indirect = n->status.indirect || e->options & OPTION_INDIRECT || ((n != myself) && sockaddrcmp(&n->address, &e->reverse->address));
-
- if(e->to->distance >= 0 && (!e->to->status.indirect || indirect) && e->to->distance <= n->distance + e->weight)
- continue;
-
- e->to->distance = n->distance + e->weight;
- e->to->status.indirect = indirect;
- e->to->nexthop = (n->nexthop == myself) ? e->to : n->nexthop;
- e->to->via = indirect ? n->via : e->to;
- e->to->options = e->options;
-
- if(e->to->address.sa.sa_family == AF_UNSPEC && e->address.sa.sa_family != AF_UNKNOWN)
- update_node_udp(e->to, &e->address);