Exemplo n.º 1
0
    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;
    }
Exemplo n.º 2
0
    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));
    }
Exemplo n.º 3
0
 public AHAddress NextHop(AHAddress from, SimPacket p, out bool deliverlocally) {
   return NextHop(from, p, false, out deliverlocally);
 }
Exemplo n.º 4
0
    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);
    }