public NodeHandle pickNextHop(RouteMessage msg, Iterator<NodeHandle> i) { NodeHandle first = i.next(); if (first.getLiveness() < NodeHandle.LIVENESS_SUSPECTED) { return first; } while (i.hasNext()) { NodeHandle nh = i.next(); if (nh.getLiveness() < NodeHandle.LIVENESS_SUSPECTED) { return nh; } // do this in case first is dead, and we find a suspected node to pass it to if (first.getLiveness() > nh.getLiveness()) first = nh; } if (first.getLiveness() >= NodeHandle.LIVENESS_DEAD) { // drop the message, this would happen if we gave a lease to this node // but found him faulty. return null; } msg.getOptions().setRerouteIfSuspected(false); return first; // always want to return someone... }
/** * Receive and process a route message. Sets a nextHop. * * @param msg the message. */ private void receiveRouteMessage(RouteMessage msg) { if (logger.level <= Logger.FINER) logger.log("receiveRouteMessage(" + msg + ")"); Id target = msg.getTarget(); if (target == null) target = thePastryNode.getNodeId(); int cwSize = thePastryNode.getLeafSet().cwSize(); int ccwSize = thePastryNode.getLeafSet().ccwSize(); int lsPos = thePastryNode.getLeafSet().mostSimilar(target); if (lsPos == 0) { // message is for the local node so deliver it msg.setNextHop(thePastryNode.getLocalHandle()); // don't return, we want to check for routing table hole } else { msg.getOptions().setRerouteIfSuspected(true); Iterator<NodeHandle> i = getBestRoutingCandidates(target); // the next hop NodeHandle nextHop = routerStrategy.pickNextHop(msg, i); if (nextHop == null) { msg.sendFailed(new NoLegalRouteToMakeProgressException(target)); return; } msg.setNextHop(nextHop); } // this wasn't being called often enough in its previous location, moved here Aug 11, 2006 checkForRouteTableHole(msg, msg.getNextHop()); msg.setPrevNode(thePastryNode.getLocalHandle()); // here, we need to deliver the msg to the proper app deliverToApplication(msg); }