diff --git a/simulator/config/example.cfg b/simulator/config/example.cfg index 3179e900..acc832c7 100755 --- a/simulator/config/example.cfg +++ b/simulator/config/example.cfg @@ -46,6 +46,7 @@ protocol.3kademlia peersim.kademlia.KademliaProtocol protocol.3kademlia.transport 2unreltr protocol.3kademlia.BITS 256 protocol.3kademlia.NBUCKETS 17 +protocol.3kademlia.FINDMODE 0 # ::::: INITIALIZERS ::::: diff --git a/simulator/src/main/java/peersim/kademlia/KademliaCommonConfig.java b/simulator/src/main/java/peersim/kademlia/KademliaCommonConfig.java index 1d009eb2..c108df3e 100755 --- a/simulator/src/main/java/peersim/kademlia/KademliaCommonConfig.java +++ b/simulator/src/main/java/peersim/kademlia/KademliaCommonConfig.java @@ -19,6 +19,7 @@ public class KademliaCommonConfig { public static int MAXREPLACEMENT = 10; // number of items in the replacement list for each bucket public static int FINDMODE = 0; // find mode: 0 find by node id / 1 find by distance to node + /** * short information about current mspastry configuration * diff --git a/simulator/src/main/java/peersim/kademlia/KademliaProtocol.java b/simulator/src/main/java/peersim/kademlia/KademliaProtocol.java index 45edf606..09dfe3ee 100755 --- a/simulator/src/main/java/peersim/kademlia/KademliaProtocol.java +++ b/simulator/src/main/java/peersim/kademlia/KademliaProtocol.java @@ -197,10 +197,13 @@ private void handleResponse(Message m, int myPid) { if (neighbour != null) { // create a new request to send to neighbour Message request = new Message(Message.MSG_FIND); + if (KademliaCommonConfig.FINDMODE == 1) request = new Message(Message.MSG_FIND_DIST); request.operationId = m.operationId; request.src = this.getNode(); request.dest = m.dest; request.body = fop.destNode; + if (KademliaCommonConfig.FINDMODE == 1) + request.body = Util.distance(fop.destNode, (BigInteger) fop.body); // increment hop count fop.nrHops++; @@ -241,10 +244,14 @@ private void handleResponse(Message m, int myPid) { private void handleFind(Message m, int myPid) { // get the ALPHA closest node to destNode - logger.info("handleFind " + (BigInteger) m.body); - - BigInteger[] neighbours = this.routingTable.getNeighbours((BigInteger) m.body, m.src.getId()); + logger.info("handleFind received"); + BigInteger[] neighbours = new BigInteger[KademliaCommonConfig.K]; + if (m.getType() == Message.MSG_FIND) { + neighbours = this.routingTable.getNeighbours((BigInteger) m.body, m.src.getId()); + } else if (m.getType() == Message.MSG_FIND_DIST) { + neighbours = this.routingTable.getNeighbours((int) m.body); + } // for (BigInteger neigh : neighbours) logger.warning("Neighbours " + neigh); // create a response message containing the neighbours (with the same id of the request) Message response = new Message(Message.MSG_RESPONSE, neighbours); @@ -284,7 +291,7 @@ private void handleInitFind(Message m, int myPid) { // set message operation id m.operationId = fop.operationId; - m.type = Message.MSG_FIND; + m.src = this.getNode(); // send ALPHA messages @@ -293,6 +300,12 @@ private void handleInitFind(Message m, int myPid) { if (nextNode != null) { m.dest = nodeIdtoNode(nextNode).getKademliaProtocol().getNode(); // new KademliaNode(nextNode); + // set message type depending on find mode + if (KademliaCommonConfig.FINDMODE == 0) m.type = Message.MSG_FIND; + else { + m.type = Message.MSG_FIND_DIST; + m.body = Util.distance(nextNode, (BigInteger) fop.body); + } logger.info("sendMessage to " + nextNode); @@ -325,7 +338,7 @@ public void sendMessage(Message m, BigInteger destId, int myPid) { transport = (UnreliableTransport) (Network.prototype).getProtocol(tid); transport.send(src, dest, m, kademliaid); - if (m.getType() == Message.MSG_FIND) { // is a request + if (m.getType() == Message.MSG_FIND || m.getType() == Message.MSG_FIND_DIST) { // is a request Timeout t = new Timeout(destId, m.id, m.operationId); long latency = transport.getLatency(src, dest); @@ -362,6 +375,7 @@ public void processEvent(Node myNode, int myPid, Object event) { break; case Message.MSG_FIND: + case Message.MSG_FIND_DIST: m = (Message) event; handleFind(m, myPid); break; diff --git a/simulator/src/main/java/peersim/kademlia/RoutingTable.java b/simulator/src/main/java/peersim/kademlia/RoutingTable.java index d023bf7e..d26e095c 100755 --- a/simulator/src/main/java/peersim/kademlia/RoutingTable.java +++ b/simulator/src/main/java/peersim/kademlia/RoutingTable.java @@ -65,6 +65,23 @@ public void removeNeighbour(BigInteger node) { bucketAtDistance(Util.distance(nodeId, node)).removeNeighbour(node); } + // return the neighbours with a specific common prefix len + public BigInteger[] getNeighbours(final int dist) { + BigInteger[] result = new BigInteger[0]; + ArrayList resultList = new ArrayList(); + resultList.addAll(bucketAtDistance(dist).neighbours.keySet()); + + if (resultList.size() < k && (dist + 1) <= 256) { + resultList.addAll(bucketAtDistance(dist + 1).neighbours.keySet()); + while (resultList.size() > k) resultList.remove(resultList.size() - 1); + } + if (resultList.size() < k & (dist - 1) >= 0) { + resultList.addAll(bucketAtDistance(dist - 1).neighbours.keySet()); + while (resultList.size() > k) resultList.remove(resultList.size() - 1); + } + return resultList.toArray(result); + } + // return the closest neighbour to a key from the correct k-bucket public BigInteger[] getNeighbours(final BigInteger key, final BigInteger src) { // resulting neighbours @@ -85,7 +102,7 @@ public BigInteger[] getNeighbours(final BigInteger key, final BigInteger src) { // else get k closest node from all k-buckets prefix_len = 0; while (prefix_len < KademliaCommonConfig.BITS) { - neighbour_candidates.addAll(k_buckets.get(prefix_len).neighbours.keySet()); + neighbour_candidates.addAll(bucketAtDistance(prefix_len).neighbours.keySet()); // remove source id neighbour_candidates.remove(src); prefix_len++;