// $Id: DVNode.java,v 1.13 2007/11/08 07:14:17 zahorjan Exp $ /** * Distance Vector algorithm implementing node. * If you want to tune the DV algorithm, this is the place. */ public class DVNode extends Node { public DVNode() { } /** * When this node is selected to run during a time step, the "driver" * code in Node.java: *
    *
  1. first calls this routine (startUpdate()) *
  2. then with high, but not certain, probability calls processUpdate() * for each update packet in the node's queue *
  3. * (1) and (3) allow some flexibility in the implementation of * different (sub)classes of node, without having to meddle with the * code in Node.java. */ protected void startUpdate() { // have routing table keep track of any changes. getRoutingTable().startLog(); } /** * Called for each update packet in this node's queue * when it is selected to run during a time step. */ protected void processUpdate(UpdatePacket udp) { // We update our route to a destination if: // - sender claims it can get there quicker than what we have advertised, or // - we're now routing through sender DVUpdatePacket p = (DVUpdatePacket)udp; // it's possible that the log didn't exist when the update // packet was sent. if ( p.log == null ) return; Node fromNode = p.fromNode; // now process the log entries in the update message for ( RoutingTable.LogEntry logEntry : p.log ) { Node dest = logEntry.dest; int newDist = logEntry.dist; if ( newDist < ConstAlg.INFINITY ) newDist++; if ( getRoutingTable().getDistTo(dest) > newDist || getRoutingTable().getHopTo(dest) == fromNode ) { getRoutingTable().setEntry(dest, fromNode, newDist); } } } /** * See comment before startUpdate(). */ protected void stopUpdate() { getRoutingTable().stopLog(); // finally, send neighbors an update if ( !hasFailed() ) { for ( Node n : neighbor ) { sendUpdatePacket(n, new DVUpdatePacket(this, getRoutingTable().getLog())); } } } /** * This method is invoked (by Node.java) when a previously * running node goes down. *

    * You are honor bound to throw away any information your * node may have cached when this happens. (Node.java will * have already thrown out what it knows about, i.e., the * routing table.) */ protected void failureEvent() { // nothing to do. } /** * This method is invoked (by Node.java) when a previously * failed node comes back online. When the node failed, * Node.java assigned it a new RoutingTable object, with * the entries for all destinations set to "no next hop". * You can/must do here anything you think is necessary. *

    * Because the base implementation depends on the logging * done by the RouterTable object, we must force all * "no path to the destination" entries into it. * We do that here. (Note that RouterTable.startLogging() * has already been called (by startUpdate()) when control * reaches this point.) *

    * Node.java sets the routing table entry for this node to * itself correctly when you return from this method. */ protected void recoveryEvent() { // The node already doesn't currently know how to get to anyone. // Have to set the routing table entries again here, though, // so that they're entered in the log. getRoutingTable().startLog(); for ( Node o: Network.getNetwork().getNodeArray() ) { getRoutingTable().setEntry(o, null, ConstAlg.INFINITY); } } /** * Invoked when a timeout indicates that a neighbor node * has failed. */ protected void neighborFailureEvent(Node neighbor) { // We haven't been keep information about which of // our neighbors can reach which destinations -- just // the nextHop info in the actual routing table. // So, when a neighbor fails, we don't really have a way // to look for an alternate path to the destinations // we're using that neighbor for. // look for any rt entries with n as the next hop // and set the next hop to null and the distance to // infinity getRoutingTable().clearTableOf(neighbor); } }