public override Pair<Connection, bool> NextConnection(Edge from, AHHeader head) {
Address dest = head.Destination;
int d_idx = _structs.IndexOf(dest);
if( d_idx >= 0 ) {
//We have a direct connection:
Connection next = _structs[d_idx];
if( next != _local_con ) {
return new Pair<Connection,bool>(next, false);
}
else {
return new Pair<Connection, bool>(null, true);
}
}
else {
var ah_dest = (AHAddress)dest;
int left_idx = ~d_idx;
Connection l_c = _structs[left_idx];
int right_idx = left_idx - 1;
Connection r_c = _structs[right_idx];
Connection next_con;
Connection other_con;
if( ah_dest.IsCloserToFirst((AHAddress)l_c.Address, (AHAddress)r_c.Address) ) {
next_con = l_c;
other_con = r_c;
}
else {
next_con = r_c;
other_con = l_c;
}
//See if we need to get it:
/* everyone gets "path" packets,
* if it's exact, only the destination gets it, handled above
* otherwise, only the two nodes on either side of the destination get
* it
*/
bool local = head.Opts == AHHeader.Options.Path ||
((next_con == _local_con || other_con == _local_con)
&& head.Opts != AHHeader.Options.Exact);
Connection to_send;
//Check not to send it back the way it came:
if(from == null) {
/*
* This packet is from us, so just send it to the closest
* node, other than us.
*/
to_send = _local_con != next_con ? next_con : other_con;
}
else if(next_con.State.Edge == from) {
//Don't send it back the way it came:
to_send = other_con;
}
else {
//Great, the closest has not yet been visited:
to_send = next_con;
}
//Now, make sure not to send it to ourselves:
to_send = to_send == _local_con ? null : to_send;
return new Pair<Connection, bool>(to_send, local);
}
}
}