}
protected void handleJoinRequest(Message jr) {
int ttl = jr.getInt(DMT.TTL);
int uid = jr.getInt(DMT.UID);
Peer joiner = (Peer) jr.getObject(DMT.JOINER);
if (joiner.isNull()) {
joiner = jr.getSource();
}
if (joiner.equals(_rt.getPeer())) {
Logger.warning("Received join request from self! Ignoring");
return;
}
_usm.send(jr.getSource(), DMT.createJoinRequestAck(uid));
HashSet dontConsider = new HashSet();
// Don't route to the joiner, or the guy who sent it to us
dontConsider.add(joiner);
dontConsider.add(jr.getSource());
LinkedList exclude;
if (jr.isSet(DMT.EXCLUDE)) {
exclude = (LinkedList) jr.getObject(DMT.EXCLUDE);
dontConsider.add(exclude);
} else {
exclude = new LinkedList();
}
while (true) {
Logger.info("LOOP: Forward joinRequest");
Peer best = _rt.findClosest(joiner.getHash(), dontConsider);
/*
* Terminate request and respond if: 1) TTL has expired 2) We couldn't find anywhere to route to
*/
if ((ttl == 0) || (best == null) || ttl < Dijjer.JOINTTL) {
LinkedList peers = new LinkedList();
peers.add(_rt.getPeer());
_rt.addPeer(joiner);
_usm.send(jr.getSource(), DMT.createJoinResponse(uid, peers));
break;
}
exclude.add(new Integer(RoutingTable.getRoutingTable().getPeer().hashCode()));
_usm.send(best, DMT.createJoinRequest(uid, joiner, jr.getInt(DMT.TTL) - 1, exclude));
Message jra = _usm.waitFor(MessageFilter.create(6000, DMT.joinRequestAck).addType(DMT.rejectDueToLoop)
.setField(DMT.UID, uid));
if (jra == null) {
_rt.recontactPeer(best);
continue;
}
if (jra.getSpec().equals(DMT.rejectDueToLoop)) {
dontConsider.add(best);
Logger.warning("joinRequest (uid: " + uid + ") rejected by " + jra.getSource() + " due to loop");
continue;
}
Message jrs = _usm.waitFor(MessageFilter.create(1000 * (ttl + 3), DMT.joinResponse).setSource(best)
.setField(DMT.UID, uid));
if (jrs == null) {
LinkedList peers = new LinkedList();
peers.add(_rt.getPeer());
_rt.addPeer(joiner);
_usm.send(jr.getSource(), DMT.createJoinResponse(uid, peers));
break;
} else {
LinkedList peers = (LinkedList) jrs.getObject(DMT.PEERS);
if (_rt.getPeers().size() < _rt.getMaxSize()) {
peers.add(_rt.getPeer());
_rt.addPeer(joiner);
}
// If any are null assume they are the sender of the joinResponse
for (ListIterator i = peers.listIterator(); i.hasNext();) {
Peer p = (Peer) i.next();
if (p.isNull()) {
i.remove();
}
}
_usm.send(jr.getSource(), DMT.createJoinResponse(uid, peers));
break;