public AHAddress NextHop(AHAddress from, SimPacket p, bool debug, out bool deliverlocally) { Debug.WriteLineIf(debug, "src:" + p.Source + ", dest:" + p.Destination); Debug.WriteLineIf(debug, "Dumping local connections for:" + this.LocalAddress.ToString()); foreach(AHAddress cons in _con_table.GetAllConnections()) { Debug.WriteLineIf(debug, cons.ToString()); } AHAddress next_node = null; deliverlocally = false; AHAddress dest = (AHAddress)p.Destination; if( p.Hops > SimPacket.MAX_TTL) { Debug.WriteLineIf(debug, "TTL exceeded."); next_node = null; } else if ( LocalAddress.Equals(dest) ) { Debug.WriteLineIf(debug, "Destination reached."); deliverlocally = true; next_node = null; } else { /* * else we know hops < ttl, we can route: * We now need to check the ConnectionTable */ int dest_idx = _con_table.IndexOf(dest); if( dest_idx >= 0 ) { //We actually have a connection to this node: next_node = _con_table.GetByIndex(dest_idx); Debug.WriteLineIf(debug, "We actually have a connection to that node."); } else if( _con_table.GetTotalCount() == 0) { //We don't have any structured connections. I guess we are the closest: Debug.WriteLineIf(debug, "No structured connections"); deliverlocally = true; next_node = null; } else { dest_idx = ~dest_idx; /* * Here are the right and left neighbors of the destination * left is increasing, right is decreasing. * Remember the ConnectionTable wraps around, so no need to worry * about the size of index */ int left_idx = dest_idx; AHAddress left_n = _con_table.GetByIndex(left_idx); int right_idx = dest_idx - 1; AHAddress right_n = _con_table.GetByIndex(right_idx); //We check the a couple of connections: BigInteger l_dist = dest.DistanceTo((AHAddress)left_n).abs(); BigInteger r_dist = dest.DistanceTo((AHAddress)right_n).abs(); AHAddress closest_node; AHAddress other_node; BigInteger closest_dist; BigInteger other_dist; if( l_dist < r_dist ) { closest_node = left_n; other_node = right_n; closest_dist = l_dist; other_dist = r_dist; Debug.WriteLineIf(debug, "Left seems closest:" + left_n.ToString()); } else { closest_node = right_n; other_node = left_n; closest_dist = r_dist; other_dist = l_dist; Debug.WriteLineIf(debug, "Right seems closest:" + right_n.ToString()); } if (p.Mode == RoutingMode.Greedy) { Debug.WriteLineIf(debug, "Executing greedy routing mode. "); BigInteger our_dist = dest.DistanceTo(this.LocalAddress).abs(); if( closest_dist < our_dist ) { if( closest_node != from ) { next_node = closest_node; Debug.WriteLineIf(debug, "Closest distance less that our distance (valid next node)."); } else { next_node = null; Debug.WriteLineIf(debug, "Closest distance less that our distance. (but still setting to null)"); } deliverlocally = false; } else { next_node = null; deliverlocally = true; Debug.WriteLineIf(debug, "Looks like we are the closest."); } } else //other routing modes { Debug.WriteLineIf(debug, "Executing other routing modes. "); int our_idx = _con_table.IndexOf(this.LocalAddress); Debug.Assert(our_idx < 0,"I cannot be in my own routing table:" + our_idx); //Compute our left neighbor. if( our_idx < 0 ) { our_idx = ~our_idx; } AHAddress our_left_n = _con_table.GetByIndex(our_idx); if( left_n == our_left_n ) { Debug.WriteLineIf(debug, "Common neighbor case: " + our_left_n); /* * We share a common left neighbor, so we should deliver locally * This is the only case where we should deliver locally, * otherwise there is at least one node on either side of the * target, so one of them should probably get the packet. */ deliverlocally = true; //The next step should be the node on the "other side" if(this.LocalAddress.IsLeftOf( dest ) ) { Debug.WriteLineIf(debug, "We are to the left. "); next_node = right_n; } else { Debug.WriteLineIf(debug, "We are to the right. "); next_node = left_n; } if(from == next_node) { //Console.WriteLine("setting next node to null"); next_node = null; } } else if ( p.Hops == 0 ) { /* * This is the case that we sent the packet, and we are not * a neighbor of the packet (the previous case) * So, the closest_con must be good since we are the source */ Debug.WriteLineIf(debug, "0 hops, still good to go."); next_node = closest_node; } else if (p.Hops <= SimPacket.MAX_UPHILL_HOPS ) { /* * We will allow the packet to go uphill (get further from the source) * at first, but this has to stop in order to prevent loops * * This may help the network form in the massive join case, or under * heavy churn. @todo analyze approaches for improving stabilization * in massively disordered cases. */ Debug.WriteLineIf(debug, "Uphill hops. "); if( closest_node != from ) { //Awesome. This is an easy case... Debug.WriteLineIf(debug, "Still good to go. "); next_node = closest_node; } else { Debug.WriteLineIf(debug, "The second closest case. "); /* * Look at the two next closest and choose the minimum distance of * the three */ int sc_idx = -1; if( closest_node == right_n ) { //move one over sc_idx = right_idx - 1; } else { //Must be the left: sc_idx = left_idx + 1; } AHAddress second_closest = _con_table.GetByIndex(sc_idx); BigInteger second_dist = dest.DistanceTo( (AHAddress)second_closest).abs(); if( second_dist < other_dist ) { other_node = second_closest; } if( other_node != from ) { //If we only have one neighbor, //other and closest might be the same next_node = other_node; } else { //We just can't win... //Console.WriteLine("setting next node to null (cannot win)"); next_node = null; } } } else { Debug.WriteLineIf(debug, "Not a neighbor case, and beyond 2-hops. "); /* * This is the case where we are not a neighbor of the destination * according to our table, and the packet has taken at least 2 hops. */ deliverlocally = false; if( ( closest_node == from ) && ( other_node != from ) ) { closest_dist = other_dist; closest_node = other_node; } AHAddress prev = from; if( prev != null ) { BigInteger prev_dist = dest.DistanceTo( (AHAddress)prev ).abs(); if( closest_dist >= prev_dist ) { //Don't send it if you can't get it closer than it was before next_node = null; Debug.WriteLineIf(debug, "Prev distance smaller than closest. Stop."); //Console.WriteLine("setting next node to null (cannot get any closer than before)"); } else { Debug.WriteLineIf(debug, "Prev distance larger than closest. Keep going."); next_node = closest_node; } } else { //This is the case that we don't have a connection //on the Edge the packet came from, this shouldn't happen, //but it is not a disaster. Debug.WriteLineIf(debug, "Prev distance smalled than closest. "); next_node = closest_node; } }//End of non-neareast neighbor case }//End of Annealing case } //End of the case where we had to find a near route } if(p.Mode == RoutingMode.Exact) { if(this.LocalAddress.Equals(dest) ) { deliverlocally = true; next_node = null; } else { deliverlocally = false; } } return next_node; }
public static void DoInexactRouting() { // // Analyse routing for keys. (large number of keys). // int network_size = sorted_node_list.Count; double greedy_inconsistent = 0; double annealing_inconsistent = 0; int max_destinations = 0; Hashtable annealing_destinations = new Hashtable(); double greedy_success_hop_count = 0.0; double greedy_fail_hop_count = 0.0; double greedy_all_hop_count = 0.0; double annealing_success_hop_count = 0.0; double annealing_fail_hop_count = 0.0; double annealing_all_hop_count = 0.0; for (int i = 0; i < key_list.Length; i++) { if (i%1000 == 0) { Console.WriteLine("current greedy inconsistent: {0}", greedy_inconsistent); Console.WriteLine("current annealing inconsistent: {0}", annealing_inconsistent); } AHAddress key = key_list[i]; //first determine the left and right int left_idx = sorted_node_list.BinarySearch(key); if (left_idx > 0) { Console.WriteLine("astronomically improbable."); continue; } left_idx = ~left_idx; left_idx = left_idx%network_size; int right_idx = left_idx - 1; if (right_idx < 0) { right_idx += network_size; } SimNode left = (SimNode) address_to_node[(AHAddress) sorted_node_list[left_idx]]; SimNode right = (SimNode) address_to_node[(AHAddress) sorted_node_list[right_idx]]; // source the key at different nodes in the network. foreach (SimNode n in address_to_node.Values) { ArrayList destinations = new ArrayList(); SimPacket p = new SimPacket(n.LocalAddress, key, RoutingMode.Greedy); SimNode curr = n; AHAddress prev_addr = null; while (true) { bool deliverlocally; AHAddress next = curr.NextHop(prev_addr, p, out deliverlocally); if (deliverlocally) { destinations.Add(curr); } if (next == null) { break; } prev_addr = curr.LocalAddress; curr = (SimNode) address_to_node[next]; p.Hops += 1; } //lets see how well we did if (destinations.Contains(left) || destinations.Contains(right)) { //we are good. greedy_success_hop_count += p.Hops; } else { greedy_inconsistent += 1; greedy_fail_hop_count += p.Hops; } greedy_all_hop_count += p.Hops; //now do annealing routing for the keys destinations = new ArrayList(); p = new SimPacket(n.LocalAddress, key, RoutingMode.Annealing); curr = n; prev_addr = null; while (true) { bool deliverlocally; AHAddress next = curr.NextHop(prev_addr, p, out deliverlocally); if (deliverlocally) { destinations.Add(curr); } if (next == null) { break; } prev_addr = curr.LocalAddress; curr = (SimNode) address_to_node[next]; p.Hops += 1; } //lets see how well we did if (destinations.Contains(left) || destinations.Contains(right)) { //we are good. annealing_success_hop_count += p.Hops ; } else { annealing_inconsistent += 1; annealing_fail_hop_count += p.Hops; } annealing_all_hop_count += p.Hops; if (destinations.Contains(left)) { destinations.Remove(left); } if (destinations.Contains(right)) { destinations.Remove(right); } int x = destinations.Count; if (annealing_destinations.Contains(x)) { int y = (int) annealing_destinations[x]; annealing_destinations[x] = y + 1; } else { annealing_destinations[x] = 1; } if (x > max_destinations) { max_destinations = x; } //Console.WriteLine("destinations.count: {0}", destinations.Count); } } Console.WriteLine("total greedy inconsistent: {0}", greedy_inconsistent); Console.WriteLine("Average (greedy) inconsistency per key: {0}", greedy_inconsistent/(1.0*key_list.Length)); Console.WriteLine("hop count (greedy, fail): {0}", greedy_fail_hop_count/greedy_inconsistent); Console.WriteLine("hop count (greedy, success): {0}", greedy_success_hop_count/(network_size*key_list.Length - greedy_inconsistent)); Console.WriteLine("average hop count (greedy): {0}", greedy_all_hop_count/(network_size*key_list.Length)); Console.WriteLine("total annealing inconsistent: {0}", annealing_inconsistent); Console.WriteLine("Average (annealing) inconsistency per key: {0}", annealing_inconsistent/(1.0*key_list.Length)); Console.WriteLine("distribution of annealing destinations"); for (int i = 0; i <= max_destinations; i++) { Console.WriteLine("dist annealing {0} {1}", i, (int) annealing_destinations[i]); } Console.WriteLine("hop count (annealing, fail): {0}", annealing_fail_hop_count/annealing_inconsistent); Console.WriteLine("hop count (annealing, success): {0}", annealing_success_hop_count/(network_size*key_list.Length - annealing_inconsistent)); Console.WriteLine("average hop count (annealing): {0}", annealing_all_hop_count/(network_size*key_list.Length)); }
public AHAddress NextHop(AHAddress from, SimPacket p, out bool deliverlocally) { return NextHop(from, p, false, out deliverlocally); }
public static void DoExactRouting() { // // Analyse exact (greedy, annealing) routing. // int network_size = sorted_node_list.Count; Console.WriteLine("Analysing exact (greedy, annealing) routing"); int greedy_broken_routes = 0; double greedy_success_hop_count = 0.0; double greedy_fail_hop_count = 0.0; double greedy_all_hop_count = 0.0; double greedy_destinations = 0.0; //double greedy_tunnel_hops_fail = 0.0; //double greedy_tunnel_hops_success = 0.0; //double greedy_tunnel_hops_all = 0.0; double greedy_real_fail = 0.0; double greedy_real_success = 0.0; double greedy_real_all = 0.0; int annealing_broken_routes = 0; double annealing_success_hop_count = 0.0; double annealing_fail_hop_count = 0.0; double annealing_all_hop_count = 0.0; double annealing_destinations = 0.0; int annealing_sucks = 0; foreach (SimNode n1 in address_to_node.Values) { foreach (SimNode n2 in address_to_node.Values) { bool greedy_success = false; bool annealing_success = false; ArrayList destinations = new ArrayList(); SimPacket p = new SimPacket(n1.LocalAddress, n2.LocalAddress, RoutingMode.Greedy); SimNode curr = n1; AHAddress prev_addr = null; int real_hops = 0; while (true) { bool deliverlocally; AHAddress next = curr.NextHop(prev_addr, p, out deliverlocally); if (deliverlocally) { destinations.Add(curr); } if (next == null) { break; } if (curr.ConnectionTable.IndexOf(next) < 0) { Console.WriteLine("Taking a wrong hop."); } SimNode next_node = (SimNode) address_to_node[next]; bool tunnel_hop = false; //if this hop was over a tunnel edge. //we can infer this from the authorizer. if (!authorizer.Allow(curr, next_node)) { tunnel_hop = true; } prev_addr = curr.LocalAddress; curr = next_node; p.Hops += 1; //add another hop if it is a tunnel hop if (tunnel_hop) { real_hops += 2; } else { real_hops += 1; } } greedy_destinations += destinations.Count; if (!destinations.Contains(n2)) { greedy_broken_routes += 1; greedy_fail_hop_count += p.Hops; greedy_real_fail += real_hops; } else { greedy_success_hop_count += p.Hops; greedy_success = true; greedy_real_success += real_hops; } greedy_all_hop_count += p.Hops; greedy_real_all += real_hops; //also check annealing in the same loop destinations = new ArrayList(); p = new SimPacket(n1.LocalAddress, n2.LocalAddress, RoutingMode.Exact); real_hops = 0; curr = n1; prev_addr = null; while (true) { bool deliverlocally; AHAddress next = curr.NextHop(prev_addr, p, out deliverlocally); if (deliverlocally) { destinations.Add(curr); } if (next == null) { break; } if (curr.ConnectionTable.IndexOf(next) < 0) { Console.WriteLine("Taking a wrong hop."); } SimNode next_node = (SimNode) address_to_node[next]; bool tunnel_hop = false; //if this hop was over a tunnel edge. //we can infer this from the authorizer. if (!authorizer.Allow(curr, next_node)) { tunnel_hop = true; } prev_addr = curr.LocalAddress; curr = next_node; p.Hops += 1; if (tunnel_hop) { real_hops += 2; } else { real_hops += 1; } } annealing_destinations += destinations.Count; if (!destinations.Contains(n2)) { annealing_broken_routes += 1; annealing_fail_hop_count += p.Hops; if (p.Hops >= 99) { Console.WriteLine("ttl expired for annealing"); } } else { annealing_success_hop_count += p.Hops; annealing_success = true; //Console.WriteLine("success: {0}", p.Hops); } annealing_all_hop_count += p.Hops; if (greedy_success && !annealing_success) { Console.WriteLine("annealing sucks"); annealing_sucks += 1; } } } Console.WriteLine("broken pairs (greedy): {0}", greedy_broken_routes); Console.WriteLine("hop count (greedy, fail): {0}", greedy_fail_hop_count/greedy_broken_routes); Console.WriteLine("hop count (greedy, success): {0}", greedy_success_hop_count/(network_size*network_size - greedy_broken_routes)); Console.WriteLine("average hop count (greedy): {0}", greedy_all_hop_count/(network_size*network_size)); Console.WriteLine("real hop count (greedy, fail): {0}", greedy_real_fail/greedy_broken_routes); Console.WriteLine("real hop count (greedy, success): {0}", greedy_real_success/(network_size*network_size - greedy_broken_routes)); Console.WriteLine("real average hop count (greedy): {0}", greedy_real_all/(network_size*network_size)); Console.WriteLine("destinations (greedy): {0}", greedy_destinations/(network_size*network_size)); Console.WriteLine("broken pairs (annealing): {0}", annealing_broken_routes); Console.WriteLine("hop count (annealing, fail): {0}", annealing_fail_hop_count/annealing_broken_routes); Console.WriteLine("hop count (annealing, success): {0}", annealing_success_hop_count/(network_size*network_size - annealing_broken_routes)); Console.WriteLine("average hop count (annealing): {0}", annealing_all_hop_count/(network_size*network_size)); Console.WriteLine("destinations (annealing): {0}", annealing_destinations/(network_size*network_size)); Console.WriteLine("sucks (annealing): {0}", annealing_sucks); }