mirror of
https://github.com/ChronosX88/KademliaDHT.git
synced 2024-11-22 02:02:21 +00:00
Some major major changes to the entire Kademlia System.
Kademlia Node - The Kademlia class is renamed to KademliaNode - this will now serve as the main node on the network - The RoutingTable will be a part of this node Node - The node class is now a basic class containing information about a node to be used by peers on the network RoutingTable - Working on Evicting contacts from the routing table - Working on Replacement Cache - Written another simulation to test these new RoutingTable features
This commit is contained in:
parent
a2f48d2241
commit
54ac3fe740
@ -34,7 +34,7 @@ import kademlia.util.serializer.JsonRoutingTableSerializer;
|
|||||||
import kademlia.util.serializer.JsonSerializer;
|
import kademlia.util.serializer.JsonSerializer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The main Kademlia network management class
|
* The main Kademlia Node on the network, this node manages everything for this local system.
|
||||||
*
|
*
|
||||||
* @author Joshua Kissoon
|
* @author Joshua Kissoon
|
||||||
* @since 20140215
|
* @since 20140215
|
||||||
@ -43,7 +43,7 @@ import kademlia.util.serializer.JsonSerializer;
|
|||||||
* @todo Handle IPv6 Addresses
|
* @todo Handle IPv6 Addresses
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class Kademlia
|
public class KademliaNode
|
||||||
{
|
{
|
||||||
|
|
||||||
/* Kademlia Attributes */
|
/* Kademlia Attributes */
|
||||||
@ -53,6 +53,7 @@ public class Kademlia
|
|||||||
private final transient Node localNode;
|
private final transient Node localNode;
|
||||||
private final transient KadServer server;
|
private final transient KadServer server;
|
||||||
private final transient DHT dht;
|
private final transient DHT dht;
|
||||||
|
private transient RoutingTable routingTable;
|
||||||
private final transient Timer timer;
|
private final transient Timer timer;
|
||||||
private final int udpPort;
|
private final int udpPort;
|
||||||
private transient KadConfiguration config;
|
private transient KadConfiguration config;
|
||||||
@ -66,24 +67,26 @@ public class Kademlia
|
|||||||
* The instance is bootstraped to an existing network by specifying the
|
* The instance is bootstraped to an existing network by specifying the
|
||||||
* address of a bootstrap node in the network.
|
* address of a bootstrap node in the network.
|
||||||
*
|
*
|
||||||
* @param ownerId The Name of this node used for storage
|
* @param ownerId The Name of this node used for storage
|
||||||
* @param localNode The Local Node for this Kad instance
|
* @param localNode The Local Node for this Kad instance
|
||||||
* @param udpPort The UDP port to use for routing messages
|
* @param udpPort The UDP port to use for routing messages
|
||||||
* @param dht The DHT for this instance
|
* @param dht The DHT for this instance
|
||||||
* @param config
|
* @param config
|
||||||
|
* @param routingTable
|
||||||
*
|
*
|
||||||
* @throws IOException If an error occurred while reading id or local map
|
* @throws IOException If an error occurred while reading id or local map
|
||||||
* from disk <i>or</i> a network error occurred while
|
* from disk <i>or</i> a network error occurred while
|
||||||
* attempting to bootstrap to the network
|
* attempting to bootstrap to the network
|
||||||
* */
|
* */
|
||||||
public Kademlia(String ownerId, Node localNode, int udpPort, DHT dht, KadConfiguration config) throws IOException
|
public KademliaNode(String ownerId, Node localNode, int udpPort, DHT dht, RoutingTable routingTable, KadConfiguration config) throws IOException
|
||||||
{
|
{
|
||||||
this.ownerId = ownerId;
|
this.ownerId = ownerId;
|
||||||
this.udpPort = udpPort;
|
this.udpPort = udpPort;
|
||||||
this.localNode = localNode;
|
this.localNode = localNode;
|
||||||
this.dht = dht;
|
this.dht = dht;
|
||||||
this.config = config;
|
this.config = config;
|
||||||
this.messageFactory = new MessageFactory(localNode, this.dht, this.config);
|
this.routingTable = routingTable;
|
||||||
|
this.messageFactory = new MessageFactory(this, this.dht, this.config);
|
||||||
this.server = new KadServer(udpPort, this.messageFactory, this.localNode, this.config);
|
this.server = new KadServer(udpPort, this.messageFactory, this.localNode, this.config);
|
||||||
this.timer = new Timer(true);
|
this.timer = new Timer(true);
|
||||||
|
|
||||||
@ -97,7 +100,7 @@ public class Kademlia
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
/* Runs a DHT RefreshOperation */
|
/* Runs a DHT RefreshOperation */
|
||||||
Kademlia.this.refresh();
|
KademliaNode.this.refresh();
|
||||||
}
|
}
|
||||||
catch (IOException e)
|
catch (IOException e)
|
||||||
{
|
{
|
||||||
@ -110,15 +113,35 @@ public class Kademlia
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Kademlia(String ownerId, NodeId defaultId, int udpPort, KadConfiguration config) throws IOException
|
public KademliaNode(String ownerId, NodeId defaultId, int udpPort, RoutingTable routingTable, KadConfiguration config) throws IOException
|
||||||
{
|
{
|
||||||
this(ownerId, new Node(defaultId, InetAddress.getLocalHost(), udpPort), udpPort, new DHT(ownerId, config), config);
|
this(ownerId,
|
||||||
|
new Node(defaultId, InetAddress.getLocalHost(), udpPort, config),
|
||||||
|
udpPort,
|
||||||
|
routingTable,
|
||||||
|
new DHT(ownerId, config), config);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Kademlia(String ownerId, NodeId defaultId, int udpPort) throws IOException
|
public KademliaNode(String ownerId, Node node, int udpPort, KadConfiguration config) throws IOException
|
||||||
{
|
{
|
||||||
this(ownerId, new Node(defaultId, InetAddress.getLocalHost(), udpPort), udpPort,
|
this(
|
||||||
new DHT(ownerId, new DefaultConfiguration()), new DefaultConfiguration());
|
ownerId,
|
||||||
|
node,
|
||||||
|
udpPort,
|
||||||
|
new DHT(ownerId, config),
|
||||||
|
new RoutingTable(node, config),
|
||||||
|
config
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public KademliaNode(String ownerId, NodeId defaultId, int udpPort) throws IOException
|
||||||
|
{
|
||||||
|
this(
|
||||||
|
ownerId,
|
||||||
|
new Node(defaultId, InetAddress.getLocalHost(), udpPort),
|
||||||
|
udpPort,
|
||||||
|
new DefaultConfiguration()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -131,9 +154,9 @@ public class Kademlia
|
|||||||
* @throws java.io.FileNotFoundException
|
* @throws java.io.FileNotFoundException
|
||||||
* @throws java.lang.ClassNotFoundException
|
* @throws java.lang.ClassNotFoundException
|
||||||
*/
|
*/
|
||||||
public static Kademlia loadFromFile(String ownerId) throws FileNotFoundException, IOException, ClassNotFoundException
|
public static KademliaNode loadFromFile(String ownerId) throws FileNotFoundException, IOException, ClassNotFoundException
|
||||||
{
|
{
|
||||||
return Kademlia.loadFromFile(ownerId, new DefaultConfiguration());
|
return KademliaNode.loadFromFile(ownerId, new DefaultConfiguration());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -147,7 +170,7 @@ public class Kademlia
|
|||||||
* @throws java.io.FileNotFoundException
|
* @throws java.io.FileNotFoundException
|
||||||
* @throws java.lang.ClassNotFoundException
|
* @throws java.lang.ClassNotFoundException
|
||||||
*/
|
*/
|
||||||
public static Kademlia loadFromFile(String ownerId, KadConfiguration iconfig) throws FileNotFoundException, IOException, ClassNotFoundException
|
public static KademliaNode loadFromFile(String ownerId, KadConfiguration iconfig) throws FileNotFoundException, IOException, ClassNotFoundException
|
||||||
{
|
{
|
||||||
DataInputStream din;
|
DataInputStream din;
|
||||||
|
|
||||||
@ -155,7 +178,7 @@ public class Kademlia
|
|||||||
* @section Read Basic Kad data
|
* @section Read Basic Kad data
|
||||||
*/
|
*/
|
||||||
din = new DataInputStream(new FileInputStream(getStateStorageFolderName(ownerId, iconfig) + File.separator + "kad.kns"));
|
din = new DataInputStream(new FileInputStream(getStateStorageFolderName(ownerId, iconfig) + File.separator + "kad.kns"));
|
||||||
Kademlia ikad = new JsonSerializer<Kademlia>().read(din);
|
KademliaNode ikad = new JsonSerializer<KademliaNode>().read(din);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @section Read the routing table
|
* @section Read the routing table
|
||||||
@ -168,7 +191,6 @@ public class Kademlia
|
|||||||
*/
|
*/
|
||||||
din = new DataInputStream(new FileInputStream(getStateStorageFolderName(ownerId, iconfig) + File.separator + "node.kns"));
|
din = new DataInputStream(new FileInputStream(getStateStorageFolderName(ownerId, iconfig) + File.separator + "node.kns"));
|
||||||
Node inode = new JsonSerializer<Node>().read(din);
|
Node inode = new JsonSerializer<Node>().read(din);
|
||||||
inode.setRoutingTable(irtbl);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @section Read the DHT
|
* @section Read the DHT
|
||||||
@ -177,7 +199,7 @@ public class Kademlia
|
|||||||
DHT idht = new JsonDHTSerializer().read(din);
|
DHT idht = new JsonDHTSerializer().read(din);
|
||||||
idht.setConfiguration(iconfig);
|
idht.setConfiguration(iconfig);
|
||||||
|
|
||||||
return new Kademlia(ownerId, inode, ikad.getPort(), idht, iconfig);
|
return new KademliaNode(ownerId, inode, ikad.getPort(), idht, irtbl, iconfig);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -223,7 +245,7 @@ public class Kademlia
|
|||||||
* */
|
* */
|
||||||
public synchronized final void bootstrap(Node n) throws IOException, RoutingException
|
public synchronized final void bootstrap(Node n) throws IOException, RoutingException
|
||||||
{
|
{
|
||||||
Operation op = new ConnectOperation(this.server, this.localNode, n, this.config);
|
Operation op = new ConnectOperation(this.server, this, n, this.config);
|
||||||
op.execute();
|
op.execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -240,7 +262,7 @@ public class Kademlia
|
|||||||
*/
|
*/
|
||||||
public synchronized int put(KadContent content) throws IOException
|
public synchronized int put(KadContent content) throws IOException
|
||||||
{
|
{
|
||||||
StoreOperation sop = new StoreOperation(this.server, this.localNode, content, this.dht, this.config);
|
StoreOperation sop = new StoreOperation(this.server, this, content, this.dht, this.config);
|
||||||
sop.execute();
|
sop.execute();
|
||||||
|
|
||||||
/* Return how many nodes the content was stored on */
|
/* Return how many nodes the content was stored on */
|
||||||
@ -279,7 +301,7 @@ public class Kademlia
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Seems like it doesn't exist in our DHT, get it from other Nodes */
|
/* Seems like it doesn't exist in our DHT, get it from other Nodes */
|
||||||
ContentLookupOperation clo = new ContentLookupOperation(server, localNode, param, this.config);
|
ContentLookupOperation clo = new ContentLookupOperation(server, this, param, this.config);
|
||||||
clo.execute();
|
clo.execute();
|
||||||
return clo.getContentFound();
|
return clo.getContentFound();
|
||||||
}
|
}
|
||||||
@ -291,7 +313,7 @@ public class Kademlia
|
|||||||
*/
|
*/
|
||||||
public void refresh() throws IOException
|
public void refresh() throws IOException
|
||||||
{
|
{
|
||||||
new KadRefreshOperation(this.server, this.localNode, this.dht, this.config).execute();
|
new KadRefreshOperation(this.server, this, this.dht, this.config).execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -343,7 +365,7 @@ public class Kademlia
|
|||||||
* @section Store Basic Kad data
|
* @section Store Basic Kad data
|
||||||
*/
|
*/
|
||||||
dout = new DataOutputStream(new FileOutputStream(getStateStorageFolderName(this.ownerId, this.config) + File.separator + "kad.kns"));
|
dout = new DataOutputStream(new FileOutputStream(getStateStorageFolderName(this.ownerId, this.config) + File.separator + "kad.kns"));
|
||||||
new JsonSerializer<Kademlia>().write(this, dout);
|
new JsonSerializer<KademliaNode>().write(this, dout);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @section Save the node state
|
* @section Save the node state
|
||||||
@ -357,7 +379,7 @@ public class Kademlia
|
|||||||
* This will cause a serialization recursion, and in turn a Stack Overflow
|
* This will cause a serialization recursion, and in turn a Stack Overflow
|
||||||
*/
|
*/
|
||||||
dout = new DataOutputStream(new FileOutputStream(getStateStorageFolderName(this.ownerId, this.config) + File.separator + "routingtable.kns"));
|
dout = new DataOutputStream(new FileOutputStream(getStateStorageFolderName(this.ownerId, this.config) + File.separator + "routingtable.kns"));
|
||||||
new JsonRoutingTableSerializer().write(this.localNode.getRoutingTable(), dout);
|
new JsonRoutingTableSerializer().write(this.getRoutingTable(), dout);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @section Save the DHT
|
* @section Save the DHT
|
||||||
@ -384,6 +406,11 @@ public class Kademlia
|
|||||||
return nodeStateFolder.toString();
|
return nodeStateFolder.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public RoutingTable getRoutingTable()
|
||||||
|
{
|
||||||
|
return this.routingTable;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a string containing all data about this Kademlia instance
|
* Creates a string containing all data about this Kademlia instance
|
||||||
*
|
*
|
||||||
@ -403,7 +430,7 @@ public class Kademlia
|
|||||||
|
|
||||||
sb.append("\n");
|
sb.append("\n");
|
||||||
sb.append("Routing Table: ");
|
sb.append("Routing Table: ");
|
||||||
sb.append(this.localNode.getRoutingTable());
|
sb.append(this.getRoutingTable());
|
||||||
sb.append("\n");
|
sb.append("\n");
|
||||||
|
|
||||||
sb.append("\n");
|
sb.append("\n");
|
@ -14,7 +14,7 @@ public class DefaultConfiguration implements KadConfiguration
|
|||||||
private final static long RESPONSE_TIMEOUT = 1500;
|
private final static long RESPONSE_TIMEOUT = 1500;
|
||||||
private final static long OPERATION_TIMEOUT = 3000;
|
private final static long OPERATION_TIMEOUT = 3000;
|
||||||
private final static int CONCURRENCY = 10;
|
private final static int CONCURRENCY = 10;
|
||||||
private final static int K = 10;
|
private final static int K = 3;
|
||||||
private final static int RCSIZE = 3;
|
private final static int RCSIZE = 3;
|
||||||
private final static int STALE = 1;
|
private final static int STALE = 1;
|
||||||
private final static String LOCAL_FOLDER = "kademlia";
|
private final static String LOCAL_FOLDER = "kademlia";
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
package kademlia.message;
|
package kademlia.message;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import kademlia.KademliaNode;
|
||||||
import kademlia.core.KadServer;
|
import kademlia.core.KadServer;
|
||||||
import kademlia.node.Node;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Receives a ConnectMessage and sends an AcknowledgeMessage as reply.
|
* Receives a ConnectMessage and sends an AcknowledgeMessage as reply.
|
||||||
@ -14,9 +14,9 @@ public class ConnectReceiver implements Receiver
|
|||||||
{
|
{
|
||||||
|
|
||||||
private final KadServer server;
|
private final KadServer server;
|
||||||
private final Node localNode;
|
private final KademliaNode localNode;
|
||||||
|
|
||||||
public ConnectReceiver(KadServer server, Node local)
|
public ConnectReceiver(KadServer server, KademliaNode local)
|
||||||
{
|
{
|
||||||
this.server = server;
|
this.server = server;
|
||||||
this.localNode = local;
|
this.localNode = local;
|
||||||
@ -38,7 +38,7 @@ public class ConnectReceiver implements Receiver
|
|||||||
this.localNode.getRoutingTable().insert(mess.getOrigin());
|
this.localNode.getRoutingTable().insert(mess.getOrigin());
|
||||||
|
|
||||||
/* Respond to the connect request */
|
/* Respond to the connect request */
|
||||||
AcknowledgeMessage msg = new AcknowledgeMessage(this.localNode);
|
AcknowledgeMessage msg = new AcknowledgeMessage(this.localNode.getNode());
|
||||||
|
|
||||||
/* Reply to the connect message with an Acknowledgement */
|
/* Reply to the connect message with an Acknowledgement */
|
||||||
this.server.reply(mess.getOrigin(), msg, comm);
|
this.server.reply(mess.getOrigin(), msg, comm);
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
package kademlia.message;
|
package kademlia.message;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import kademlia.KademliaNode;
|
||||||
import kademlia.core.KadConfiguration;
|
import kademlia.core.KadConfiguration;
|
||||||
import kademlia.core.KadServer;
|
import kademlia.core.KadServer;
|
||||||
import kademlia.dht.DHT;
|
import kademlia.dht.DHT;
|
||||||
import kademlia.node.Node;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Responds to a ContentLookupMessage by sending a ContentMessage containing the requested content;
|
* Responds to a ContentLookupMessage by sending a ContentMessage containing the requested content;
|
||||||
@ -17,11 +17,11 @@ public class ContentLookupReceiver implements Receiver
|
|||||||
{
|
{
|
||||||
|
|
||||||
private final KadServer server;
|
private final KadServer server;
|
||||||
private final Node localNode;
|
private final KademliaNode localNode;
|
||||||
private final DHT dht;
|
private final DHT dht;
|
||||||
private final KadConfiguration config;
|
private final KadConfiguration config;
|
||||||
|
|
||||||
public ContentLookupReceiver(KadServer server, Node localNode, DHT dht, KadConfiguration config)
|
public ContentLookupReceiver(KadServer server, KademliaNode localNode, DHT dht, KadConfiguration config)
|
||||||
{
|
{
|
||||||
this.server = server;
|
this.server = server;
|
||||||
this.localNode = localNode;
|
this.localNode = localNode;
|
||||||
@ -42,7 +42,7 @@ public class ContentLookupReceiver implements Receiver
|
|||||||
if (this.dht.contains(msg.getParameters()))
|
if (this.dht.contains(msg.getParameters()))
|
||||||
{
|
{
|
||||||
/* Return a ContentMessage with the required data */
|
/* Return a ContentMessage with the required data */
|
||||||
ContentMessage cMsg = new ContentMessage(localNode, this.dht.get(msg.getParameters()));
|
ContentMessage cMsg = new ContentMessage(localNode.getNode(), this.dht.get(msg.getParameters()));
|
||||||
server.reply(msg.getOrigin(), cMsg, comm);
|
server.reply(msg.getOrigin(), cMsg, comm);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -2,10 +2,10 @@ package kademlia.message;
|
|||||||
|
|
||||||
import java.io.DataInputStream;
|
import java.io.DataInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import kademlia.KademliaNode;
|
||||||
import kademlia.core.KadConfiguration;
|
import kademlia.core.KadConfiguration;
|
||||||
import kademlia.core.KadServer;
|
import kademlia.core.KadServer;
|
||||||
import kademlia.dht.DHT;
|
import kademlia.dht.DHT;
|
||||||
import kademlia.node.Node;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles creating messages and receivers
|
* Handles creating messages and receivers
|
||||||
@ -16,11 +16,11 @@ import kademlia.node.Node;
|
|||||||
public class MessageFactory
|
public class MessageFactory
|
||||||
{
|
{
|
||||||
|
|
||||||
private final Node localNode;
|
private final KademliaNode localNode;
|
||||||
private final DHT dht;
|
private final DHT dht;
|
||||||
private final KadConfiguration config;
|
private final KadConfiguration config;
|
||||||
|
|
||||||
public MessageFactory(Node local, DHT dht, KadConfiguration config)
|
public MessageFactory(KademliaNode local, DHT dht, KadConfiguration config)
|
||||||
{
|
{
|
||||||
this.localNode = local;
|
this.localNode = local;
|
||||||
this.dht = dht;
|
this.dht = dht;
|
||||||
@ -64,12 +64,10 @@ public class MessageFactory
|
|||||||
return new ContentLookupReceiver(server, this.localNode, this.dht, this.config);
|
return new ContentLookupReceiver(server, this.localNode, this.dht, this.config);
|
||||||
case NodeLookupMessage.CODE:
|
case NodeLookupMessage.CODE:
|
||||||
return new NodeLookupReceiver(server, this.localNode, this.config);
|
return new NodeLookupReceiver(server, this.localNode, this.config);
|
||||||
case SimpleMessage.CODE:
|
|
||||||
return new SimpleReceiver();
|
|
||||||
case StoreContentMessage.CODE:
|
case StoreContentMessage.CODE:
|
||||||
return new StoreContentReceiver(server, this.localNode, this.dht);
|
return new StoreContentReceiver(server, this.localNode, this.dht);
|
||||||
default:
|
default:
|
||||||
System.out.println("No reveiver found for message. Code: " + code);
|
System.out.println("No receiver found for message. Code: " + code);
|
||||||
return new SimpleReceiver();
|
return new SimpleReceiver();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@ package kademlia.message;
|
|||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import kademlia.KademliaNode;
|
||||||
import kademlia.core.KadConfiguration;
|
import kademlia.core.KadConfiguration;
|
||||||
import kademlia.core.KadServer;
|
import kademlia.core.KadServer;
|
||||||
import kademlia.node.Node;
|
import kademlia.node.Node;
|
||||||
@ -16,10 +17,10 @@ public class NodeLookupReceiver implements Receiver
|
|||||||
{
|
{
|
||||||
|
|
||||||
private final KadServer server;
|
private final KadServer server;
|
||||||
private final Node localNode;
|
private final KademliaNode localNode;
|
||||||
private final KadConfiguration config;
|
private final KadConfiguration config;
|
||||||
|
|
||||||
public NodeLookupReceiver(KadServer server, Node local, KadConfiguration config)
|
public NodeLookupReceiver(KadServer server, KademliaNode local, KadConfiguration config)
|
||||||
{
|
{
|
||||||
this.server = server;
|
this.server = server;
|
||||||
this.localNode = local;
|
this.localNode = local;
|
||||||
@ -48,7 +49,7 @@ public class NodeLookupReceiver implements Receiver
|
|||||||
List<Node> nodes = this.localNode.getRoutingTable().findClosest(msg.getLookupId(), this.config.k());
|
List<Node> nodes = this.localNode.getRoutingTable().findClosest(msg.getLookupId(), this.config.k());
|
||||||
|
|
||||||
/* Respond to the NodeLookupMessage */
|
/* Respond to the NodeLookupMessage */
|
||||||
Message reply = new NodeReplyMessage(this.localNode, nodes);
|
Message reply = new NodeReplyMessage(this.localNode.getNode(), nodes);
|
||||||
|
|
||||||
/* Let the Server send the reply */
|
/* Let the Server send the reply */
|
||||||
this.server.reply(origin, reply, comm);
|
this.server.reply(origin, reply, comm);
|
||||||
|
@ -89,6 +89,6 @@ public class NodeReplyMessage implements Message
|
|||||||
@Override
|
@Override
|
||||||
public String toString()
|
public String toString()
|
||||||
{
|
{
|
||||||
return "ConnectMessage[origin NodeId=" + origin.getNodeId() + "]";
|
return "NodeReplyMessage[origin NodeId=" + origin.getNodeId() + "]";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
package kademlia.message;
|
package kademlia.message;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import kademlia.KademliaNode;
|
||||||
import kademlia.core.KadServer;
|
import kademlia.core.KadServer;
|
||||||
import kademlia.dht.DHT;
|
import kademlia.dht.DHT;
|
||||||
import kademlia.node.Node;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Receiver for incoming StoreContentMessage
|
* Receiver for incoming StoreContentMessage
|
||||||
@ -15,10 +15,10 @@ public class StoreContentReceiver implements Receiver
|
|||||||
{
|
{
|
||||||
|
|
||||||
private final KadServer server;
|
private final KadServer server;
|
||||||
private final Node localNode;
|
private final KademliaNode localNode;
|
||||||
private final DHT dht;
|
private final DHT dht;
|
||||||
|
|
||||||
public StoreContentReceiver(KadServer server, Node localNode, DHT dht)
|
public StoreContentReceiver(KadServer server, KademliaNode localNode, DHT dht)
|
||||||
{
|
{
|
||||||
this.server = server;
|
this.server = server;
|
||||||
this.localNode = localNode;
|
this.localNode = localNode;
|
||||||
|
@ -7,10 +7,9 @@ import java.net.InetAddress;
|
|||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.net.SocketAddress;
|
import java.net.SocketAddress;
|
||||||
import kademlia.message.Streamable;
|
import kademlia.message.Streamable;
|
||||||
import kademlia.routing.RoutingTable;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A Node in the Kademlia network
|
* A Node in the Kademlia network - Contains basic node network information.
|
||||||
*
|
*
|
||||||
* @author Joshua Kissoon
|
* @author Joshua Kissoon
|
||||||
* @since 20140202
|
* @since 20140202
|
||||||
@ -24,15 +23,12 @@ public class Node implements Streamable
|
|||||||
private int port;
|
private int port;
|
||||||
private final String strRep;
|
private final String strRep;
|
||||||
|
|
||||||
private transient RoutingTable routingTable;
|
|
||||||
|
|
||||||
public Node(NodeId nid, InetAddress ip, int port)
|
public Node(NodeId nid, InetAddress ip, int port)
|
||||||
{
|
{
|
||||||
this.nodeId = nid;
|
this.nodeId = nid;
|
||||||
this.inetAddress = ip;
|
this.inetAddress = ip;
|
||||||
this.port = port;
|
this.port = port;
|
||||||
this.strRep = this.nodeId.toString();
|
this.strRep = this.nodeId.toString();
|
||||||
this.routingTable = new RoutingTable(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -109,24 +105,6 @@ public class Node implements Streamable
|
|||||||
this.port = in.readInt();
|
this.port = in.readInt();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return The RoutingTable of this Node
|
|
||||||
*/
|
|
||||||
public RoutingTable getRoutingTable()
|
|
||||||
{
|
|
||||||
return this.routingTable;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets a new routing table to this node, mainly used when we retrieve the node from a saved state
|
|
||||||
*
|
|
||||||
* @param tbl The routing table to use
|
|
||||||
*/
|
|
||||||
public void setRoutingTable(RoutingTable tbl)
|
|
||||||
{
|
|
||||||
this.routingTable = tbl;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object o)
|
public boolean equals(Object o)
|
||||||
{
|
{
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
package kademlia.operation;
|
package kademlia.operation;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import kademlia.KademliaNode;
|
||||||
import kademlia.core.KadConfiguration;
|
import kademlia.core.KadConfiguration;
|
||||||
import kademlia.core.KadServer;
|
import kademlia.core.KadServer;
|
||||||
import kademlia.node.Node;
|
|
||||||
import kademlia.node.NodeId;
|
import kademlia.node.NodeId;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -17,10 +17,10 @@ public class BucketRefreshOperation implements Operation
|
|||||||
{
|
{
|
||||||
|
|
||||||
private final KadServer server;
|
private final KadServer server;
|
||||||
private final Node localNode;
|
private final KademliaNode localNode;
|
||||||
private final KadConfiguration config;
|
private final KadConfiguration config;
|
||||||
|
|
||||||
public BucketRefreshOperation(KadServer server, Node localNode, KadConfiguration config)
|
public BucketRefreshOperation(KadServer server, KademliaNode localNode, KadConfiguration config)
|
||||||
{
|
{
|
||||||
this.server = server;
|
this.server = server;
|
||||||
this.localNode = localNode;
|
this.localNode = localNode;
|
||||||
@ -43,7 +43,7 @@ public class BucketRefreshOperation implements Operation
|
|||||||
for (int i = 1; i < NodeId.ID_LENGTH; i++)
|
for (int i = 1; i < NodeId.ID_LENGTH; i++)
|
||||||
{
|
{
|
||||||
/* Construct a NodeId that is i bits away from the current node Id */
|
/* Construct a NodeId that is i bits away from the current node Id */
|
||||||
final NodeId current = this.localNode.getNodeId().generateNodeIdByDistance(i);
|
final NodeId current = this.localNode.getNode().getNodeId().generateNodeIdByDistance(i);
|
||||||
|
|
||||||
/* Run the Node Lookup Operation, each in a different thread to speed up things */
|
/* Run the Node Lookup Operation, each in a different thread to speed up things */
|
||||||
new Thread()
|
new Thread()
|
||||||
@ -53,7 +53,7 @@ public class BucketRefreshOperation implements Operation
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
new NodeLookupOperation(server, localNode, localNode.getNodeId(), BucketRefreshOperation.this.config).execute();
|
new NodeLookupOperation(server, localNode, localNode.getNode().getNodeId(), BucketRefreshOperation.this.config).execute();
|
||||||
}
|
}
|
||||||
catch (IOException e)
|
catch (IOException e)
|
||||||
{
|
{
|
||||||
|
@ -7,6 +7,7 @@ package kademlia.operation;
|
|||||||
|
|
||||||
import kademlia.message.Receiver;
|
import kademlia.message.Receiver;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import kademlia.KademliaNode;
|
||||||
import kademlia.core.KadConfiguration;
|
import kademlia.core.KadConfiguration;
|
||||||
import kademlia.core.KadServer;
|
import kademlia.core.KadServer;
|
||||||
import kademlia.exceptions.RoutingException;
|
import kademlia.exceptions.RoutingException;
|
||||||
@ -21,7 +22,7 @@ public class ConnectOperation implements Operation, Receiver
|
|||||||
public static final int MAX_CONNECT_ATTEMPTS = 5; // Try 5 times to connect to a node
|
public static final int MAX_CONNECT_ATTEMPTS = 5; // Try 5 times to connect to a node
|
||||||
|
|
||||||
private final KadServer server;
|
private final KadServer server;
|
||||||
private final Node localNode;
|
private final KademliaNode localNode;
|
||||||
private final Node bootstrapNode;
|
private final Node bootstrapNode;
|
||||||
private final KadConfiguration config;
|
private final KadConfiguration config;
|
||||||
|
|
||||||
@ -34,7 +35,7 @@ public class ConnectOperation implements Operation, Receiver
|
|||||||
* @param bootstrap Node to use to bootstrap the local node onto the network
|
* @param bootstrap Node to use to bootstrap the local node onto the network
|
||||||
* @param config
|
* @param config
|
||||||
*/
|
*/
|
||||||
public ConnectOperation(KadServer server, Node local, Node bootstrap, KadConfiguration config)
|
public ConnectOperation(KadServer server, KademliaNode local, Node bootstrap, KadConfiguration config)
|
||||||
{
|
{
|
||||||
this.server = server;
|
this.server = server;
|
||||||
this.localNode = local;
|
this.localNode = local;
|
||||||
@ -50,7 +51,7 @@ public class ConnectOperation implements Operation, Receiver
|
|||||||
/* Contact the bootstrap node */
|
/* Contact the bootstrap node */
|
||||||
this.error = true;
|
this.error = true;
|
||||||
this.attempts = 0;
|
this.attempts = 0;
|
||||||
Message m = new ConnectMessage(this.localNode);
|
Message m = new ConnectMessage(this.localNode.getNode());
|
||||||
|
|
||||||
/* Send a connect message to the bootstrap node */
|
/* Send a connect message to the bootstrap node */
|
||||||
server.sendMessage(this.bootstrapNode, m, this);
|
server.sendMessage(this.bootstrapNode, m, this);
|
||||||
@ -77,7 +78,7 @@ public class ConnectOperation implements Operation, Receiver
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Perform lookup for our own ID to get nodes close to us */
|
/* Perform lookup for our own ID to get nodes close to us */
|
||||||
Operation lookup = new NodeLookupOperation(this.server, this.localNode, this.localNode.getNodeId(), this.config);
|
Operation lookup = new NodeLookupOperation(this.server, this.localNode, this.localNode.getNode().getNodeId(), this.config);
|
||||||
lookup.execute();
|
lookup.execute();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -127,7 +128,7 @@ public class ConnectOperation implements Operation, Receiver
|
|||||||
{
|
{
|
||||||
if (++this.attempts < MAX_CONNECT_ATTEMPTS)
|
if (++this.attempts < MAX_CONNECT_ATTEMPTS)
|
||||||
{
|
{
|
||||||
this.server.sendMessage(this.bootstrapNode, new ConnectMessage(this.localNode), this);
|
this.server.sendMessage(this.bootstrapNode, new ConnectMessage(this.localNode.getNode()), this);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -10,6 +10,7 @@ import java.util.List;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.SortedMap;
|
import java.util.SortedMap;
|
||||||
import java.util.TreeMap;
|
import java.util.TreeMap;
|
||||||
|
import kademlia.KademliaNode;
|
||||||
import kademlia.dht.GetParameter;
|
import kademlia.dht.GetParameter;
|
||||||
import kademlia.core.KadConfiguration;
|
import kademlia.core.KadConfiguration;
|
||||||
import kademlia.core.KadServer;
|
import kademlia.core.KadServer;
|
||||||
@ -40,7 +41,7 @@ public class ContentLookupOperation implements Operation, Receiver
|
|||||||
private static final Byte FAILED = (byte) 0x03;
|
private static final Byte FAILED = (byte) 0x03;
|
||||||
|
|
||||||
private final KadServer server;
|
private final KadServer server;
|
||||||
private final Node localNode;
|
private final KademliaNode localNode;
|
||||||
private StorageEntry contentFound = null;
|
private StorageEntry contentFound = null;
|
||||||
private final KadConfiguration config;
|
private final KadConfiguration config;
|
||||||
|
|
||||||
@ -67,10 +68,10 @@ public class ContentLookupOperation implements Operation, Receiver
|
|||||||
* @param params The parameters to search for the content which we need to find
|
* @param params The parameters to search for the content which we need to find
|
||||||
* @param config
|
* @param config
|
||||||
*/
|
*/
|
||||||
public ContentLookupOperation(KadServer server, Node localNode, GetParameter params, KadConfiguration config)
|
public ContentLookupOperation(KadServer server, KademliaNode localNode, GetParameter params, KadConfiguration config)
|
||||||
{
|
{
|
||||||
/* Construct our lookup message */
|
/* Construct our lookup message */
|
||||||
this.lookupMessage = new ContentLookupMessage(localNode, params);
|
this.lookupMessage = new ContentLookupMessage(localNode.getNode(), params);
|
||||||
|
|
||||||
this.server = server;
|
this.server = server;
|
||||||
this.localNode = localNode;
|
this.localNode = localNode;
|
||||||
@ -94,7 +95,7 @@ public class ContentLookupOperation implements Operation, Receiver
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
/* Set the local node as already asked */
|
/* Set the local node as already asked */
|
||||||
nodes.put(this.localNode, ASKED);
|
nodes.put(this.localNode.getNode(), ASKED);
|
||||||
|
|
||||||
this.addNodes(this.localNode.getRoutingTable().getAllNodes());
|
this.addNodes(this.localNode.getRoutingTable().getAllNodes());
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@ package kademlia.operation;
|
|||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import kademlia.KademliaNode;
|
||||||
import kademlia.core.KadConfiguration;
|
import kademlia.core.KadConfiguration;
|
||||||
import kademlia.core.KadServer;
|
import kademlia.core.KadServer;
|
||||||
import kademlia.dht.DHT;
|
import kademlia.dht.DHT;
|
||||||
@ -21,11 +22,11 @@ public class ContentRefreshOperation implements Operation
|
|||||||
{
|
{
|
||||||
|
|
||||||
private final KadServer server;
|
private final KadServer server;
|
||||||
private final Node localNode;
|
private final KademliaNode localNode;
|
||||||
private final DHT dht;
|
private final DHT dht;
|
||||||
private final KadConfiguration config;
|
private final KadConfiguration config;
|
||||||
|
|
||||||
public ContentRefreshOperation(KadServer server, Node localNode, DHT dht, KadConfiguration config)
|
public ContentRefreshOperation(KadServer server, KademliaNode localNode, DHT dht, KadConfiguration config)
|
||||||
{
|
{
|
||||||
this.server = server;
|
this.server = server;
|
||||||
this.localNode = localNode;
|
this.localNode = localNode;
|
||||||
@ -66,7 +67,7 @@ public class ContentRefreshOperation implements Operation
|
|||||||
List<Node> closestNodes = this.localNode.getRoutingTable().findClosest(e.getKey(), this.config.k());
|
List<Node> closestNodes = this.localNode.getRoutingTable().findClosest(e.getKey(), this.config.k());
|
||||||
|
|
||||||
/* Create the message */
|
/* Create the message */
|
||||||
Message msg = new StoreContentMessage(this.localNode, dht.get(e));
|
Message msg = new StoreContentMessage(this.localNode.getNode(), dht.get(e));
|
||||||
|
|
||||||
/*Store the message on all of the K-Nodes*/
|
/*Store the message on all of the K-Nodes*/
|
||||||
for (Node n : closestNodes)
|
for (Node n : closestNodes)
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
package kademlia.operation;
|
package kademlia.operation;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import kademlia.KademliaNode;
|
||||||
import kademlia.core.KadConfiguration;
|
import kademlia.core.KadConfiguration;
|
||||||
import kademlia.core.KadServer;
|
import kademlia.core.KadServer;
|
||||||
import kademlia.dht.DHT;
|
import kademlia.dht.DHT;
|
||||||
import kademlia.node.Node;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An operation that handles refreshing the entire Kademlia Systems including buckets and content
|
* An operation that handles refreshing the entire Kademlia Systems including buckets and content
|
||||||
@ -16,11 +16,11 @@ public class KadRefreshOperation implements Operation
|
|||||||
{
|
{
|
||||||
|
|
||||||
private final KadServer server;
|
private final KadServer server;
|
||||||
private final Node localNode;
|
private final KademliaNode localNode;
|
||||||
private final DHT dht;
|
private final DHT dht;
|
||||||
private final KadConfiguration config;
|
private final KadConfiguration config;
|
||||||
|
|
||||||
public KadRefreshOperation(KadServer server, Node localNode, DHT dht, KadConfiguration config)
|
public KadRefreshOperation(KadServer server, KademliaNode localNode, DHT dht, KadConfiguration config)
|
||||||
{
|
{
|
||||||
this.server = server;
|
this.server = server;
|
||||||
this.localNode = localNode;
|
this.localNode = localNode;
|
||||||
|
@ -8,6 +8,7 @@ import java.util.HashMap;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.TreeMap;
|
import java.util.TreeMap;
|
||||||
|
import kademlia.KademliaNode;
|
||||||
import kademlia.core.KadConfiguration;
|
import kademlia.core.KadConfiguration;
|
||||||
import kademlia.core.KadServer;
|
import kademlia.core.KadServer;
|
||||||
import kademlia.exceptions.RoutingException;
|
import kademlia.exceptions.RoutingException;
|
||||||
@ -35,14 +36,14 @@ public class NodeLookupOperation implements Operation, Receiver
|
|||||||
private static final String AWAITING = "Awaiting";
|
private static final String AWAITING = "Awaiting";
|
||||||
private static final String ASKED = "Asked";
|
private static final String ASKED = "Asked";
|
||||||
private static final String FAILED = "Failed";
|
private static final String FAILED = "Failed";
|
||||||
|
|
||||||
private final KadServer server;
|
private final KadServer server;
|
||||||
private final Node localNode;
|
private final KademliaNode localNode;
|
||||||
private final NodeId lookupId;
|
private final NodeId lookupId;
|
||||||
private final KadConfiguration config;
|
private final KadConfiguration config;
|
||||||
|
|
||||||
private boolean error;
|
private boolean error;
|
||||||
|
|
||||||
private final Message lookupMessage; // Message sent to each peer
|
private final Message lookupMessage; // Message sent to each peer
|
||||||
private final Map<Node, String> nodes;
|
private final Map<Node, String> nodes;
|
||||||
|
|
||||||
@ -51,7 +52,7 @@ public class NodeLookupOperation implements Operation, Receiver
|
|||||||
|
|
||||||
/* Used to sort nodes */
|
/* Used to sort nodes */
|
||||||
private final Comparator comparator;
|
private final Comparator comparator;
|
||||||
|
|
||||||
|
|
||||||
{
|
{
|
||||||
messagesTransiting = new HashMap<>();
|
messagesTransiting = new HashMap<>();
|
||||||
@ -63,14 +64,14 @@ public class NodeLookupOperation implements Operation, Receiver
|
|||||||
* @param lookupId The ID for which to find nodes close to
|
* @param lookupId The ID for which to find nodes close to
|
||||||
* @param config
|
* @param config
|
||||||
*/
|
*/
|
||||||
public NodeLookupOperation(KadServer server, Node localNode, NodeId lookupId, KadConfiguration config)
|
public NodeLookupOperation(KadServer server, KademliaNode localNode, NodeId lookupId, KadConfiguration config)
|
||||||
{
|
{
|
||||||
this.server = server;
|
this.server = server;
|
||||||
this.localNode = localNode;
|
this.localNode = localNode;
|
||||||
this.lookupId = lookupId;
|
this.lookupId = lookupId;
|
||||||
this.config = config;
|
this.config = config;
|
||||||
|
|
||||||
this.lookupMessage = new NodeLookupMessage(localNode, lookupId);
|
this.lookupMessage = new NodeLookupMessage(localNode.getNode(), lookupId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* We initialize a TreeMap to store nodes.
|
* We initialize a TreeMap to store nodes.
|
||||||
@ -93,9 +94,9 @@ public class NodeLookupOperation implements Operation, Receiver
|
|||||||
error = true;
|
error = true;
|
||||||
|
|
||||||
/* Set the local node as already asked */
|
/* Set the local node as already asked */
|
||||||
nodes.put(this.localNode, ASKED);
|
nodes.put(this.localNode.getNode(), ASKED);
|
||||||
|
|
||||||
this.addNodes(this.localNode.getRoutingTable().getAllNodes());
|
this.addNodes(this.localNode.getRoutingTable().findClosest(this.lookupId, this.config.k()));
|
||||||
|
|
||||||
/* If we haven't finished as yet, wait for a maximum of config.operationTimeout() time */
|
/* If we haven't finished as yet, wait for a maximum of config.operationTimeout() time */
|
||||||
int totalTimeWaited = 0;
|
int totalTimeWaited = 0;
|
||||||
@ -118,28 +119,16 @@ public class NodeLookupOperation implements Operation, Receiver
|
|||||||
throw new RoutingException("Lookup Timeout.");
|
throw new RoutingException("Lookup Timeout.");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/* Now after we've finished, we would have an idea of offline nodes, lets update our routing table */
|
||||||
* @deprecated - replaced by the above code
|
this.localNode.getRoutingTable().setUnresponsiveContacts(this.getFailedNodes());
|
||||||
* We just keep this code in case any problems are encountered later
|
|
||||||
*/
|
|
||||||
// if (!this.askNodesorFinish())
|
|
||||||
// {
|
|
||||||
// /* If we haven't finished as yet, wait for a maximum of OPERATION_TIMEOUT time */
|
|
||||||
// wait(this.config.operationTimeout());
|
|
||||||
//
|
|
||||||
// /* If we still haven't received any responses by then, do a routing timeout */
|
|
||||||
// if (error)
|
|
||||||
// {
|
|
||||||
// throw new RoutingException("Lookup Timeout.");
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
catch (InterruptedException e)
|
catch (InterruptedException e)
|
||||||
{
|
{
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Node> getClosestNodes()
|
public List<Node> getClosestNodes()
|
||||||
{
|
{
|
||||||
return this.closestNodes(ASKED);
|
return this.closestNodes(ASKED);
|
||||||
@ -183,7 +172,7 @@ public class NodeLookupOperation implements Operation, Receiver
|
|||||||
|
|
||||||
/* Get unqueried nodes among the K closest seen that have not FAILED */
|
/* Get unqueried nodes among the K closest seen that have not FAILED */
|
||||||
List<Node> unasked = this.closestNodesNotFailed(UNASKED);
|
List<Node> unasked = this.closestNodesNotFailed(UNASKED);
|
||||||
|
|
||||||
if (unasked.isEmpty() && this.messagesTransiting.isEmpty())
|
if (unasked.isEmpty() && this.messagesTransiting.isEmpty())
|
||||||
{
|
{
|
||||||
/* We have no unasked nodes nor any messages in transit, we're finished! */
|
/* We have no unasked nodes nor any messages in transit, we're finished! */
|
||||||
@ -198,9 +187,9 @@ public class NodeLookupOperation implements Operation, Receiver
|
|||||||
for (int i = 0; (this.messagesTransiting.size() < this.config.maxConcurrentMessagesTransiting()) && (i < unasked.size()); i++)
|
for (int i = 0; (this.messagesTransiting.size() < this.config.maxConcurrentMessagesTransiting()) && (i < unasked.size()); i++)
|
||||||
{
|
{
|
||||||
Node n = (Node) unasked.get(i);
|
Node n = (Node) unasked.get(i);
|
||||||
|
|
||||||
int comm = server.sendMessage(n, lookupMessage, this);
|
int comm = server.sendMessage(n, lookupMessage, this);
|
||||||
|
|
||||||
this.nodes.put(n, AWAITING);
|
this.nodes.put(n, AWAITING);
|
||||||
this.messagesTransiting.put(comm, n);
|
this.messagesTransiting.put(comm, n);
|
||||||
}
|
}
|
||||||
@ -218,7 +207,7 @@ public class NodeLookupOperation implements Operation, Receiver
|
|||||||
{
|
{
|
||||||
List<Node> closestNodes = new ArrayList<>(this.config.k());
|
List<Node> closestNodes = new ArrayList<>(this.config.k());
|
||||||
int remainingSpaces = this.config.k();
|
int remainingSpaces = this.config.k();
|
||||||
|
|
||||||
for (Map.Entry e : this.nodes.entrySet())
|
for (Map.Entry e : this.nodes.entrySet())
|
||||||
{
|
{
|
||||||
if (status.equals(e.getValue()))
|
if (status.equals(e.getValue()))
|
||||||
@ -231,7 +220,7 @@ public class NodeLookupOperation implements Operation, Receiver
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return closestNodes;
|
return closestNodes;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -247,7 +236,7 @@ public class NodeLookupOperation implements Operation, Receiver
|
|||||||
{
|
{
|
||||||
List<Node> closestNodes = new ArrayList<>(this.config.k());
|
List<Node> closestNodes = new ArrayList<>(this.config.k());
|
||||||
int remainingSpaces = this.config.k();
|
int remainingSpaces = this.config.k();
|
||||||
|
|
||||||
for (Map.Entry<Node, String> e : this.nodes.entrySet())
|
for (Map.Entry<Node, String> e : this.nodes.entrySet())
|
||||||
{
|
{
|
||||||
if (!FAILED.equals(e.getValue()))
|
if (!FAILED.equals(e.getValue()))
|
||||||
@ -257,14 +246,14 @@ public class NodeLookupOperation implements Operation, Receiver
|
|||||||
/* We got one with the required status, now add it */
|
/* We got one with the required status, now add it */
|
||||||
closestNodes.add(e.getKey());
|
closestNodes.add(e.getKey());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (--remainingSpaces == 0)
|
if (--remainingSpaces == 0)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return closestNodes;
|
return closestNodes;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -308,7 +297,7 @@ public class NodeLookupOperation implements Operation, Receiver
|
|||||||
{
|
{
|
||||||
/* Get the node associated with this communication */
|
/* Get the node associated with this communication */
|
||||||
Node n = this.messagesTransiting.get(new Integer(comm));
|
Node n = this.messagesTransiting.get(new Integer(comm));
|
||||||
|
|
||||||
if (n == null)
|
if (n == null)
|
||||||
{
|
{
|
||||||
throw new UnknownMessageException("Unknown comm: " + comm);
|
throw new UnknownMessageException("Unknown comm: " + comm);
|
||||||
@ -318,7 +307,22 @@ public class NodeLookupOperation implements Operation, Receiver
|
|||||||
this.nodes.put(n, FAILED);
|
this.nodes.put(n, FAILED);
|
||||||
this.localNode.getRoutingTable().remove(n);
|
this.localNode.getRoutingTable().remove(n);
|
||||||
this.messagesTransiting.remove(comm);
|
this.messagesTransiting.remove(comm);
|
||||||
|
|
||||||
this.askNodesorFinish();
|
this.askNodesorFinish();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<Node> getFailedNodes()
|
||||||
|
{
|
||||||
|
List<Node> failedNodes = new ArrayList<>();
|
||||||
|
|
||||||
|
for (Map.Entry<Node, String> e : this.nodes.entrySet())
|
||||||
|
{
|
||||||
|
if (e.getValue().equals(FAILED))
|
||||||
|
{
|
||||||
|
failedNodes.add(e.getKey());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return failedNodes;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@ package kademlia.operation;
|
|||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import kademlia.KademliaNode;
|
||||||
import kademlia.core.KadConfiguration;
|
import kademlia.core.KadConfiguration;
|
||||||
import kademlia.core.KadServer;
|
import kademlia.core.KadServer;
|
||||||
import kademlia.dht.DHT;
|
import kademlia.dht.DHT;
|
||||||
@ -21,7 +22,7 @@ public class StoreOperation implements Operation
|
|||||||
{
|
{
|
||||||
|
|
||||||
private final KadServer server;
|
private final KadServer server;
|
||||||
private final Node localNode;
|
private final KademliaNode localNode;
|
||||||
private final KadContent content;
|
private final KadContent content;
|
||||||
private final DHT localDht;
|
private final DHT localDht;
|
||||||
private final KadConfiguration config;
|
private final KadConfiguration config;
|
||||||
@ -33,7 +34,7 @@ public class StoreOperation implements Operation
|
|||||||
* @param localDht The local DHT
|
* @param localDht The local DHT
|
||||||
* @param config
|
* @param config
|
||||||
*/
|
*/
|
||||||
public StoreOperation(KadServer server, Node localNode, KadContent content, DHT localDht, KadConfiguration config)
|
public StoreOperation(KadServer server, KademliaNode localNode, KadContent content, DHT localDht, KadConfiguration config)
|
||||||
{
|
{
|
||||||
this.server = server;
|
this.server = server;
|
||||||
this.localNode = localNode;
|
this.localNode = localNode;
|
||||||
@ -51,7 +52,7 @@ public class StoreOperation implements Operation
|
|||||||
List<Node> nodes = ndlo.getClosestNodes();
|
List<Node> nodes = ndlo.getClosestNodes();
|
||||||
|
|
||||||
/* Create the message */
|
/* Create the message */
|
||||||
Message msg = new StoreContentMessage(this.localNode, new StorageEntry(this.content));
|
Message msg = new StoreContentMessage(this.localNode.getNode(), new StorageEntry(this.content));
|
||||||
|
|
||||||
/*Store the message on all of the K-Nodes*/
|
/*Store the message on all of the K-Nodes*/
|
||||||
for (Node n : nodes)
|
for (Node n : nodes)
|
||||||
|
@ -15,12 +15,19 @@ import kademlia.node.Node;
|
|||||||
public class KadBucket implements Bucket
|
public class KadBucket implements Bucket
|
||||||
{
|
{
|
||||||
|
|
||||||
|
/* How deep is this bucket in the Routing Table */
|
||||||
private final int depth;
|
private final int depth;
|
||||||
|
|
||||||
|
/* Contacts stored in this routing table */
|
||||||
private final Map<Contact, Contact> contacts;
|
private final Map<Contact, Contact> contacts;
|
||||||
|
|
||||||
|
/* A set of last seen contacts that can replace any current contact that is unresponsive */
|
||||||
|
private final Map<Contact, Contact> replacementCache;
|
||||||
|
|
||||||
|
|
||||||
{
|
{
|
||||||
contacts = new TreeMap<>(new ContactLastSeenComparator());
|
contacts = new TreeMap<>(new ContactLastSeenComparator());
|
||||||
|
replacementCache = new TreeMap<>(new ContactLastSeenComparator());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -94,9 +101,9 @@ public class KadBucket implements Bucket
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<Contact> getContacts()
|
public synchronized List<Contact> getContacts()
|
||||||
{
|
{
|
||||||
return new ArrayList<>(this.contacts.values());
|
return (this.contacts.isEmpty()) ? new ArrayList<>() : new ArrayList<>(this.contacts.values());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -2,6 +2,7 @@ package kademlia.routing;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import kademlia.core.KadConfiguration;
|
||||||
import kademlia.node.Node;
|
import kademlia.node.Node;
|
||||||
import kademlia.node.NodeId;
|
import kademlia.node.NodeId;
|
||||||
|
|
||||||
@ -17,9 +18,12 @@ public class RoutingTable
|
|||||||
private final Node localNode; // The current node
|
private final Node localNode; // The current node
|
||||||
private transient Bucket[] buckets;
|
private transient Bucket[] buckets;
|
||||||
|
|
||||||
public RoutingTable(Node localNode)
|
private final KadConfiguration config;
|
||||||
|
|
||||||
|
public RoutingTable(Node localNode, KadConfiguration config)
|
||||||
{
|
{
|
||||||
this.localNode = localNode;
|
this.localNode = localNode;
|
||||||
|
this.config = config;
|
||||||
|
|
||||||
/* Initialize all of the buckets to a specific depth */
|
/* Initialize all of the buckets to a specific depth */
|
||||||
this.initialize();
|
this.initialize();
|
||||||
@ -99,7 +103,7 @@ public class RoutingTable
|
|||||||
*
|
*
|
||||||
* @return List A List of contacts closest to target
|
* @return List A List of contacts closest to target
|
||||||
*/
|
*/
|
||||||
public final List<Node> findClosest(NodeId target, int numNodesRequired)
|
public synchronized final List<Node> findClosest(NodeId target, int numNodesRequired)
|
||||||
{
|
{
|
||||||
List<Node> closest = new ArrayList<>(numNodesRequired);
|
List<Node> closest = new ArrayList<>(numNodesRequired);
|
||||||
|
|
||||||
@ -232,14 +236,35 @@ public class RoutingTable
|
|||||||
this.buckets = buckets;
|
this.buckets = buckets;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method used by operations to notify the routing table of any contacts that have been unresponsive.
|
||||||
|
*
|
||||||
|
* @param contacts The set of unresponsive contacts
|
||||||
|
*/
|
||||||
|
public void setUnresponsiveContacts(List<Node> contacts)
|
||||||
|
{
|
||||||
|
if (contacts.isEmpty())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.println("Unresponsive contacts: ");
|
||||||
|
for (Node n : contacts)
|
||||||
|
{
|
||||||
|
System.out.println(n);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final String toString()
|
public synchronized final String toString()
|
||||||
{
|
{
|
||||||
StringBuilder sb = new StringBuilder("\nPrinting Routing Table Started ***************** \n");
|
StringBuilder sb = new StringBuilder("\nPrinting Routing Table Started ***************** \n");
|
||||||
|
int totalContacts = 0;
|
||||||
for (Bucket b : this.buckets)
|
for (Bucket b : this.buckets)
|
||||||
{
|
{
|
||||||
if (b.numContacts() > 0)
|
if (b.numContacts() > 0)
|
||||||
{
|
{
|
||||||
|
totalContacts += b.numContacts();
|
||||||
sb.append("# nodes in Bucket with depth ");
|
sb.append("# nodes in Bucket with depth ");
|
||||||
sb.append(b.getDepth());
|
sb.append(b.getDepth());
|
||||||
sb.append(": ");
|
sb.append(": ");
|
||||||
@ -249,6 +274,11 @@ public class RoutingTable
|
|||||||
sb.append("\n");
|
sb.append("\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sb.append("\nTotal Contacts: ");
|
||||||
|
sb.append(totalContacts);
|
||||||
|
sb.append("\n\n");
|
||||||
|
|
||||||
sb.append("Printing Routing Table Ended ******************** ");
|
sb.append("Printing Routing Table Ended ******************** ");
|
||||||
|
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
|
@ -3,7 +3,7 @@ package kademlia.tests;
|
|||||||
import java.util.Timer;
|
import java.util.Timer;
|
||||||
import java.util.TimerTask;
|
import java.util.TimerTask;
|
||||||
import kademlia.core.DefaultConfiguration;
|
import kademlia.core.DefaultConfiguration;
|
||||||
import kademlia.Kademlia;
|
import kademlia.KademliaNode;
|
||||||
import kademlia.core.KadConfiguration;
|
import kademlia.core.KadConfiguration;
|
||||||
import kademlia.node.NodeId;
|
import kademlia.node.NodeId;
|
||||||
|
|
||||||
@ -21,11 +21,11 @@ public class AutoRefreshOperationTest
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
/* Setting up 2 Kad networks */
|
/* Setting up 2 Kad networks */
|
||||||
final Kademlia kad1 = new Kademlia("JoshuaK", new NodeId("ASF456789djem45674DH"), 12049);
|
final KademliaNode kad1 = new KademliaNode("JoshuaK", new NodeId("ASF456789djem45674DH"), 12049);
|
||||||
final Kademlia kad2 = new Kademlia("Crystal", new NodeId("AJDHR678947584567464"), 4585);
|
final KademliaNode kad2 = new KademliaNode("Crystal", new NodeId("AJDHR678947584567464"), 4585);
|
||||||
final Kademlia kad3 = new Kademlia("Shameer", new NodeId("AS84k6789KRNS45KFJ8W"), 8104);
|
final KademliaNode kad3 = new KademliaNode("Shameer", new NodeId("AS84k6789KRNS45KFJ8W"), 8104);
|
||||||
final Kademlia kad4 = new Kademlia("Lokesh.", new NodeId("ASF45678947A845674GG"), 8335);
|
final KademliaNode kad4 = new KademliaNode("Lokesh.", new NodeId("ASF45678947A845674GG"), 8335);
|
||||||
final Kademlia kad5 = new Kademlia("Chandu.", new NodeId("AS84kUD894758456dyrj"), 13345);
|
final KademliaNode kad5 = new KademliaNode("Chandu.", new NodeId("AS84kUD894758456dyrj"), 13345);
|
||||||
|
|
||||||
/* Connecting nodes */
|
/* Connecting nodes */
|
||||||
System.out.println("Connecting Nodes");
|
System.out.println("Connecting Nodes");
|
||||||
|
@ -3,7 +3,7 @@ package kademlia.tests;
|
|||||||
import java.util.Timer;
|
import java.util.Timer;
|
||||||
import java.util.TimerTask;
|
import java.util.TimerTask;
|
||||||
import kademlia.core.DefaultConfiguration;
|
import kademlia.core.DefaultConfiguration;
|
||||||
import kademlia.Kademlia;
|
import kademlia.KademliaNode;
|
||||||
import kademlia.core.KadConfiguration;
|
import kademlia.core.KadConfiguration;
|
||||||
import kademlia.node.NodeId;
|
import kademlia.node.NodeId;
|
||||||
|
|
||||||
@ -21,9 +21,9 @@ public class AutoRefreshOperationTest2
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
/* Setting up 2 Kad networks */
|
/* Setting up 2 Kad networks */
|
||||||
final Kademlia kad1 = new Kademlia("JoshuaK", new NodeId("ASF456789djem4567463"), 12049);
|
final KademliaNode kad1 = new KademliaNode("JoshuaK", new NodeId("ASF456789djem4567463"), 12049);
|
||||||
final Kademlia kad2 = new Kademlia("Crystal", new NodeId("AS84k678DJRW84567465"), 4585);
|
final KademliaNode kad2 = new KademliaNode("Crystal", new NodeId("AS84k678DJRW84567465"), 4585);
|
||||||
final Kademlia kad3 = new Kademlia("Shameer", new NodeId("AS84k67894758456746A"), 8104);
|
final KademliaNode kad3 = new KademliaNode("Shameer", new NodeId("AS84k67894758456746A"), 8104);
|
||||||
|
|
||||||
/* Connecting nodes */
|
/* Connecting nodes */
|
||||||
System.out.println("Connecting Nodes");
|
System.out.println("Connecting Nodes");
|
||||||
|
@ -2,7 +2,7 @@ package kademlia.tests;
|
|||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import kademlia.dht.GetParameter;
|
import kademlia.dht.GetParameter;
|
||||||
import kademlia.Kademlia;
|
import kademlia.KademliaNode;
|
||||||
import kademlia.dht.StorageEntry;
|
import kademlia.dht.StorageEntry;
|
||||||
import kademlia.exceptions.ContentNotFoundException;
|
import kademlia.exceptions.ContentNotFoundException;
|
||||||
import kademlia.node.NodeId;
|
import kademlia.node.NodeId;
|
||||||
@ -21,9 +21,9 @@ public class ContentSendingTest
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
/* Setting up 2 Kad networks */
|
/* Setting up 2 Kad networks */
|
||||||
Kademlia kad1 = new Kademlia("JoshuaK", new NodeId("ASF45678947584567467"), 7574);
|
KademliaNode kad1 = new KademliaNode("JoshuaK", new NodeId("ASF45678947584567467"), 7574);
|
||||||
System.out.println("Created Node Kad 1: " + kad1.getNode().getNodeId());
|
System.out.println("Created Node Kad 1: " + kad1.getNode().getNodeId());
|
||||||
Kademlia kad2 = new Kademlia("Crystal", new NodeId("ASERTKJDHGVHERJHGFLK"), 7572);
|
KademliaNode kad2 = new KademliaNode("Crystal", new NodeId("ASERTKJDHGVHERJHGFLK"), 7572);
|
||||||
System.out.println("Created Node Kad 2: " + kad2.getNode().getNodeId());
|
System.out.println("Created Node Kad 2: " + kad2.getNode().getNodeId());
|
||||||
kad2.bootstrap(kad1.getNode());
|
kad2.bootstrap(kad1.getNode());
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@ package kademlia.tests;
|
|||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import kademlia.dht.GetParameter;
|
import kademlia.dht.GetParameter;
|
||||||
import kademlia.Kademlia;
|
import kademlia.KademliaNode;
|
||||||
import kademlia.dht.StorageEntry;
|
import kademlia.dht.StorageEntry;
|
||||||
import kademlia.exceptions.ContentNotFoundException;
|
import kademlia.exceptions.ContentNotFoundException;
|
||||||
import kademlia.node.NodeId;
|
import kademlia.node.NodeId;
|
||||||
@ -21,9 +21,9 @@ public class ContentUpdatingTest
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
/* Setting up 2 Kad networks */
|
/* Setting up 2 Kad networks */
|
||||||
Kademlia kad1 = new Kademlia("JoshuaK", new NodeId("ASF45678947584567467"), 7574);
|
KademliaNode kad1 = new KademliaNode("JoshuaK", new NodeId("ASF45678947584567467"), 7574);
|
||||||
System.out.println("Created Node Kad 1: " + kad1.getNode().getNodeId());
|
System.out.println("Created Node Kad 1: " + kad1.getNode().getNodeId());
|
||||||
Kademlia kad2 = new Kademlia("Crystal", new NodeId("ASERTKJDHGVHERJHGFLK"), 7572);
|
KademliaNode kad2 = new KademliaNode("Crystal", new NodeId("ASERTKJDHGVHERJHGFLK"), 7572);
|
||||||
System.out.println("Created Node Kad 2: " + kad2.getNode().getNodeId());
|
System.out.println("Created Node Kad 2: " + kad2.getNode().getNodeId());
|
||||||
kad2.bootstrap(kad1.getNode());
|
kad2.bootstrap(kad1.getNode());
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package kademlia.tests;
|
package kademlia.tests;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import kademlia.Kademlia;
|
import kademlia.KademliaNode;
|
||||||
import kademlia.node.NodeId;
|
import kademlia.node.NodeId;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -18,10 +18,10 @@ public class NodeConnectionTest
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
/* Setting up 2 Kad networks */
|
/* Setting up 2 Kad networks */
|
||||||
Kademlia kad1 = new Kademlia("JoshuaK", new NodeId("ASF45678947584567467"), 7574);
|
KademliaNode kad1 = new KademliaNode("JoshuaK", new NodeId("ASF45678947584567467"), 7574);
|
||||||
System.out.println("Created Node Kad 1: " + kad1.getNode().getNodeId());
|
System.out.println("Created Node Kad 1: " + kad1.getNode().getNodeId());
|
||||||
|
|
||||||
Kademlia kad2 = new Kademlia("Crystal", new NodeId("ASERTKJDHGVHERJHGFLK"), 7572);
|
KademliaNode kad2 = new KademliaNode("Crystal", new NodeId("ASERTKJDHGVHERJHGFLK"), 7572);
|
||||||
//NodeId diff12 = kad1.getNode().getNodeId().xor(kad2.getNode().getNodeId());
|
//NodeId diff12 = kad1.getNode().getNodeId().xor(kad2.getNode().getNodeId());
|
||||||
System.out.println("Created Node Kad 2: " + kad2.getNode().getNodeId());
|
System.out.println("Created Node Kad 2: " + kad2.getNode().getNodeId());
|
||||||
// System.out.println(kad1.getNode().getNodeId() + " ^ " + kad2.getNode().getNodeId() + " = " + diff12);
|
// System.out.println(kad1.getNode().getNodeId() + " ^ " + kad2.getNode().getNodeId() + " = " + diff12);
|
||||||
@ -37,7 +37,7 @@ public class NodeConnectionTest
|
|||||||
// System.out.println(kad2.getNode().getRoutingTable());
|
// System.out.println(kad2.getNode().getRoutingTable());
|
||||||
|
|
||||||
/* Creating a new node 3 and connecting it to 1, hoping it'll get onto 2 also */
|
/* Creating a new node 3 and connecting it to 1, hoping it'll get onto 2 also */
|
||||||
Kademlia kad3 = new Kademlia("Jessica", new NodeId("ASERTKJDOLKMNBVFR45G"), 7783);
|
KademliaNode kad3 = new KademliaNode("Jessica", new NodeId("ASERTKJDOLKMNBVFR45G"), 7783);
|
||||||
System.out.println("\n\n\n\n\n\nCreated Node Kad 3: " + kad3.getNode().getNodeId());
|
System.out.println("\n\n\n\n\n\nCreated Node Kad 3: " + kad3.getNode().getNodeId());
|
||||||
|
|
||||||
System.out.println("Connecting Kad 3 and Kad 2");
|
System.out.println("Connecting Kad 3 and Kad 2");
|
||||||
@ -47,20 +47,20 @@ public class NodeConnectionTest
|
|||||||
// NodeId diff31 = kad1.getNode().getNodeId().xor(kad3.getNode().getNodeId());
|
// NodeId diff31 = kad1.getNode().getNodeId().xor(kad3.getNode().getNodeId());
|
||||||
// System.out.println("Kad 3 - Kad 1 distance: " + diff31.getFirstSetBitIndex());
|
// System.out.println("Kad 3 - Kad 1 distance: " + diff31.getFirstSetBitIndex());
|
||||||
// System.out.println("Kad 3 - Kad 2 distance: " + diff32.getFirstSetBitIndex());
|
// System.out.println("Kad 3 - Kad 2 distance: " + diff32.getFirstSetBitIndex());
|
||||||
Kademlia kad4 = new Kademlia("Sandy", new NodeId("ASERTK85OLKMN85FR4SS"), 7789);
|
KademliaNode kad4 = new KademliaNode("Sandy", new NodeId("ASERTK85OLKMN85FR4SS"), 7789);
|
||||||
System.out.println("\n\n\n\n\n\nCreated Node Kad 4: " + kad4.getNode().getNodeId());
|
System.out.println("\n\n\n\n\n\nCreated Node Kad 4: " + kad4.getNode().getNodeId());
|
||||||
|
|
||||||
System.out.println("Connecting Kad 4 and Kad 2");
|
System.out.println("Connecting Kad 4 and Kad 2");
|
||||||
kad4.bootstrap(kad2.getNode());
|
kad4.bootstrap(kad2.getNode());
|
||||||
|
|
||||||
System.out.println("\n\nKad 1: " + kad1.getNode().getNodeId() + " Routing Table: ");
|
System.out.println("\n\nKad 1: " + kad1.getNode().getNodeId() + " Routing Table: ");
|
||||||
System.out.println(kad1.getNode().getRoutingTable());
|
System.out.println(kad1.getRoutingTable());
|
||||||
System.out.println("\n\nKad 2: " + kad2.getNode().getNodeId() + " Routing Table: ");
|
System.out.println("\n\nKad 2: " + kad2.getNode().getNodeId() + " Routing Table: ");
|
||||||
System.out.println(kad2.getNode().getRoutingTable());
|
System.out.println(kad2.getRoutingTable());
|
||||||
System.out.println("\n\nKad 3: " + kad3.getNode().getNodeId() + " Routing Table: ");
|
System.out.println("\n\nKad 3: " + kad3.getNode().getNodeId() + " Routing Table: ");
|
||||||
System.out.println(kad3.getNode().getRoutingTable());
|
System.out.println(kad3.getRoutingTable());
|
||||||
System.out.println("\n\nKad 4: " + kad4.getNode().getNodeId() + " Routing Table: ");
|
System.out.println("\n\nKad 4: " + kad4.getNode().getNodeId() + " Routing Table: ");
|
||||||
System.out.println(kad4.getNode().getRoutingTable());
|
System.out.println(kad4.getRoutingTable());
|
||||||
}
|
}
|
||||||
catch (IOException e)
|
catch (IOException e)
|
||||||
{
|
{
|
||||||
|
@ -2,7 +2,7 @@ package kademlia.tests;
|
|||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import kademlia.dht.GetParameter;
|
import kademlia.dht.GetParameter;
|
||||||
import kademlia.Kademlia;
|
import kademlia.KademliaNode;
|
||||||
import kademlia.dht.StorageEntry;
|
import kademlia.dht.StorageEntry;
|
||||||
import kademlia.exceptions.ContentNotFoundException;
|
import kademlia.exceptions.ContentNotFoundException;
|
||||||
import kademlia.node.NodeId;
|
import kademlia.node.NodeId;
|
||||||
@ -21,8 +21,8 @@ public class RefreshOperationTest
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
/* Setting up 2 Kad networks */
|
/* Setting up 2 Kad networks */
|
||||||
Kademlia kad1 = new Kademlia("JoshuaK", new NodeId("ASF45678947584567467"), 7574);
|
KademliaNode kad1 = new KademliaNode("JoshuaK", new NodeId("ASF45678947584567467"), 7574);
|
||||||
Kademlia kad2 = new Kademlia("Crystal", new NodeId("ASERTKJDHGVHERJHGFLK"), 7572);
|
KademliaNode kad2 = new KademliaNode("Crystal", new NodeId("ASERTKJDHGVHERJHGFLK"), 7572);
|
||||||
kad2.bootstrap(kad1.getNode());
|
kad2.bootstrap(kad1.getNode());
|
||||||
|
|
||||||
/* Lets create the content and share it */
|
/* Lets create the content and share it */
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
package kademlia.tests;
|
package kademlia.tests;
|
||||||
|
|
||||||
import kademlia.Kademlia;
|
import kademlia.KademliaNode;
|
||||||
import kademlia.node.NodeId;
|
import kademlia.node.NodeId;
|
||||||
import kademlia.routing.RoutingTable;
|
import kademlia.routing.RoutingTable;
|
||||||
|
|
||||||
@ -18,13 +18,13 @@ public class RoutingTableSimulation
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
/* Setting up 2 Kad networks */
|
/* Setting up 2 Kad networks */
|
||||||
Kademlia kad1 = new Kademlia("JoshuaK", new NodeId("ASF45678947584567463"), 12049);
|
KademliaNode kad1 = new KademliaNode("JoshuaK", new NodeId("ASF45678947584567463"), 12049);
|
||||||
Kademlia kad2 = new Kademlia("Crystal", new NodeId("ASF45678947584567464"), 4585);
|
KademliaNode kad2 = new KademliaNode("Crystal", new NodeId("ASF45678947584567464"), 4585);
|
||||||
Kademlia kad3 = new Kademlia("Shameer", new NodeId("ASF45678947584567465"), 8104);
|
KademliaNode kad3 = new KademliaNode("Shameer", new NodeId("ASF45678947584567465"), 8104);
|
||||||
Kademlia kad4 = new Kademlia("Lokesh", new NodeId("ASF45678947584567466"), 8335);
|
KademliaNode kad4 = new KademliaNode("Lokesh", new NodeId("ASF45678947584567466"), 8335);
|
||||||
Kademlia kad5 = new Kademlia("Chandu", new NodeId("ASF45678947584567467"), 13345);
|
KademliaNode kad5 = new KademliaNode("Chandu", new NodeId("ASF45678947584567467"), 13345);
|
||||||
|
|
||||||
RoutingTable rt = kad1.getNode().getRoutingTable();
|
RoutingTable rt = kad1.getRoutingTable();
|
||||||
|
|
||||||
rt.insert(kad2.getNode());
|
rt.insert(kad2.getNode());
|
||||||
rt.insert(kad3.getNode());
|
rt.insert(kad3.getNode());
|
||||||
@ -36,6 +36,9 @@ public class RoutingTableSimulation
|
|||||||
|
|
||||||
rt.insert(kad3.getNode());
|
rt.insert(kad3.getNode());
|
||||||
System.out.println(rt);
|
System.out.println(rt);
|
||||||
|
|
||||||
|
|
||||||
|
/* Lets shut down a node and then try putting a content on the network. We'll then see how the un-responsive contacts work */
|
||||||
}
|
}
|
||||||
catch (IllegalStateException e)
|
catch (IllegalStateException e)
|
||||||
{
|
{
|
||||||
|
125
src/kademlia/tests/RoutingTableStateTesting.java
Normal file
125
src/kademlia/tests/RoutingTableStateTesting.java
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
package kademlia.tests;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import kademlia.KademliaNode;
|
||||||
|
import kademlia.dht.KadContent;
|
||||||
|
import kademlia.node.NodeId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Testing how the routing table works and it's state after different operations
|
||||||
|
*
|
||||||
|
* @author Joshua Kissoon
|
||||||
|
* @since 20140426
|
||||||
|
*/
|
||||||
|
public class RoutingTableStateTesting
|
||||||
|
{
|
||||||
|
|
||||||
|
KademliaNode kad0, kad1, kad2, kad3, kad4, kad5, kad6, kad7, kad8, kad9;
|
||||||
|
|
||||||
|
public RoutingTableStateTesting()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
/* Setting up 2 Kad networks */
|
||||||
|
kad0 = new KademliaNode("user0", new NodeId("HRF456789SD584567460"), 1334);
|
||||||
|
kad1 = new KademliaNode("user1", new NodeId("ASF456789475DS567461"), 1209);
|
||||||
|
kad2 = new KademliaNode("user2", new NodeId("AFG45678947584567462"), 4585);
|
||||||
|
kad3 = new KademliaNode("user3", new NodeId("FSF45J38947584567463"), 8104);
|
||||||
|
kad4 = new KademliaNode("user4", new NodeId("ASF45678947584567464"), 8335);
|
||||||
|
kad5 = new KademliaNode("user5", new NodeId("GHF4567894DR84567465"), 13345);
|
||||||
|
kad6 = new KademliaNode("user6", new NodeId("ASF45678947584567466"), 12049);
|
||||||
|
kad7 = new KademliaNode("user7", new NodeId("AE345678947584567467"), 14585);
|
||||||
|
kad8 = new KademliaNode("user8", new NodeId("ASAA5678947584567468"), 18104);
|
||||||
|
kad9 = new KademliaNode("user9", new NodeId("ASF456789475845674U9"), 18335);
|
||||||
|
|
||||||
|
kad1.bootstrap(kad0.getNode());
|
||||||
|
kad2.bootstrap(kad0.getNode());
|
||||||
|
kad3.bootstrap(kad0.getNode());
|
||||||
|
kad4.bootstrap(kad0.getNode());
|
||||||
|
kad5.bootstrap(kad0.getNode());
|
||||||
|
kad6.bootstrap(kad0.getNode());
|
||||||
|
kad7.bootstrap(kad0.getNode());
|
||||||
|
kad8.bootstrap(kad0.getNode());
|
||||||
|
kad9.bootstrap(kad0.getNode());
|
||||||
|
|
||||||
|
/* Lets shut down a node and then try putting a content on the network. We'll then see how the un-responsive contacts work */
|
||||||
|
}
|
||||||
|
catch (IllegalStateException e)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public KadContent putContent(String content, KademliaNode owner)
|
||||||
|
{
|
||||||
|
DHTContentImpl c = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
c = new DHTContentImpl(kad2.getOwnerId(), "Some Data");
|
||||||
|
owner.put(c);
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
catch (IOException e)
|
||||||
|
{
|
||||||
|
System.err.println("Error whiles putting content " + content + " from owner: " + owner.getOwnerId());
|
||||||
|
}
|
||||||
|
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void shutdownKad(KademliaNode kad)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
kad.shutdown(false);
|
||||||
|
}
|
||||||
|
catch (IOException ex)
|
||||||
|
{
|
||||||
|
System.err.println("Error whiles shutting down node with owner: " + kad.getOwnerId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void printRoutingTables()
|
||||||
|
{
|
||||||
|
System.out.println(kad0.getRoutingTable());
|
||||||
|
System.out.println(kad1.getRoutingTable());
|
||||||
|
System.out.println(kad2.getRoutingTable());
|
||||||
|
System.out.println(kad3.getRoutingTable());
|
||||||
|
System.out.println(kad4.getRoutingTable());
|
||||||
|
System.out.println(kad5.getRoutingTable());
|
||||||
|
System.out.println(kad6.getRoutingTable());
|
||||||
|
System.out.println(kad7.getRoutingTable());
|
||||||
|
System.out.println(kad8.getRoutingTable());
|
||||||
|
System.out.println(kad9.getRoutingTable());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void printStorage()
|
||||||
|
{
|
||||||
|
System.out.println(kad0.getDHT());
|
||||||
|
System.out.println(kad1.getDHT());
|
||||||
|
System.out.println(kad2.getDHT());
|
||||||
|
System.out.println(kad3.getDHT());
|
||||||
|
System.out.println(kad4.getDHT());
|
||||||
|
System.out.println(kad5.getDHT());
|
||||||
|
System.out.println(kad6.getDHT());
|
||||||
|
System.out.println(kad7.getDHT());
|
||||||
|
System.out.println(kad8.getDHT());
|
||||||
|
System.out.println(kad9.getDHT());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args)
|
||||||
|
{
|
||||||
|
RoutingTableStateTesting rtss = new RoutingTableStateTesting();
|
||||||
|
rtss.printRoutingTables();
|
||||||
|
|
||||||
|
/* Lets shut down a node to test the node removal operation */
|
||||||
|
rtss.shutdownKad(rtss.kad3);
|
||||||
|
|
||||||
|
rtss.putContent("Content owned by kad0", rtss.kad0);
|
||||||
|
rtss.printStorage();
|
||||||
|
}
|
||||||
|
}
|
@ -1,6 +1,6 @@
|
|||||||
package kademlia.tests;
|
package kademlia.tests;
|
||||||
|
|
||||||
import kademlia.Kademlia;
|
import kademlia.KademliaNode;
|
||||||
import kademlia.node.NodeId;
|
import kademlia.node.NodeId;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -17,11 +17,11 @@ public class SaveStateTest
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
/* Setting up 2 Kad networks */
|
/* Setting up 2 Kad networks */
|
||||||
Kademlia kad1 = new Kademlia("JoshuaK", new NodeId("ASF45678947584567463"), 12049);
|
KademliaNode kad1 = new KademliaNode("JoshuaK", new NodeId("ASF45678947584567463"), 12049);
|
||||||
Kademlia kad2 = new Kademlia("Crystal", new NodeId("ASF45678947584567464"), 4585);
|
KademliaNode kad2 = new KademliaNode("Crystal", new NodeId("ASF45678947584567464"), 4585);
|
||||||
Kademlia kad3 = new Kademlia("Shameer", new NodeId("ASF45678947584567465"), 8104);
|
KademliaNode kad3 = new KademliaNode("Shameer", new NodeId("ASF45678947584567465"), 8104);
|
||||||
Kademlia kad4 = new Kademlia("Lokesh", new NodeId("ASF45678947584567466"), 8335);
|
KademliaNode kad4 = new KademliaNode("Lokesh", new NodeId("ASF45678947584567466"), 8335);
|
||||||
Kademlia kad5 = new Kademlia("Chandu", new NodeId("ASF45678947584567467"), 13345);
|
KademliaNode kad5 = new KademliaNode("Chandu", new NodeId("ASF45678947584567467"), 13345);
|
||||||
|
|
||||||
/* Connecting 2 to 1 */
|
/* Connecting 2 to 1 */
|
||||||
System.out.println("Connecting Nodes 1 & 2");
|
System.out.println("Connecting Nodes 1 & 2");
|
||||||
@ -76,7 +76,7 @@ public class SaveStateTest
|
|||||||
kad1.shutdown(true);
|
kad1.shutdown(true);
|
||||||
|
|
||||||
System.out.println("\n\n\nReloading Kad instance from file");
|
System.out.println("\n\n\nReloading Kad instance from file");
|
||||||
Kademlia kadR2 = Kademlia.loadFromFile("JoshuaK");
|
KademliaNode kadR2 = KademliaNode.loadFromFile("JoshuaK");
|
||||||
System.out.println(kadR2);
|
System.out.println(kadR2);
|
||||||
}
|
}
|
||||||
catch (IllegalStateException e)
|
catch (IllegalStateException e)
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
package kademlia.tests;
|
package kademlia.tests;
|
||||||
|
|
||||||
import kademlia.Kademlia;
|
import kademlia.KademliaNode;
|
||||||
import kademlia.dht.GetParameter;
|
import kademlia.dht.GetParameter;
|
||||||
import kademlia.dht.StorageEntry;
|
import kademlia.dht.StorageEntry;
|
||||||
import kademlia.node.NodeId;
|
import kademlia.node.NodeId;
|
||||||
@ -20,8 +20,8 @@ public class SaveStateTest2
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
/* Setting up 2 Kad networks */
|
/* Setting up 2 Kad networks */
|
||||||
Kademlia kad1 = new Kademlia("JoshuaK", new NodeId("ASF45678947584567463"), 12049);
|
KademliaNode kad1 = new KademliaNode("JoshuaK", new NodeId("ASF45678947584567463"), 12049);
|
||||||
Kademlia kad2 = new Kademlia("Crystal", new NodeId("ASF45678947584567464"), 4585);
|
KademliaNode kad2 = new KademliaNode("Crystal", new NodeId("ASF45678947584567464"), 4585);
|
||||||
|
|
||||||
/* Connecting 2 to 1 */
|
/* Connecting 2 to 1 */
|
||||||
System.out.println("Connecting Nodes 1 & 2");
|
System.out.println("Connecting Nodes 1 & 2");
|
||||||
@ -46,7 +46,7 @@ public class SaveStateTest2
|
|||||||
kad1.shutdown(true);
|
kad1.shutdown(true);
|
||||||
|
|
||||||
System.out.println("\n\n\nReloading Kad instance from file");
|
System.out.println("\n\n\nReloading Kad instance from file");
|
||||||
kad1 = Kademlia.loadFromFile("JoshuaK");
|
kad1 = KademliaNode.loadFromFile("JoshuaK");
|
||||||
kad1.bootstrap(kad2.getNode());
|
kad1.bootstrap(kad2.getNode());
|
||||||
System.out.println(kad2);
|
System.out.println(kad2);
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package kademlia.tests;
|
package kademlia.tests;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import kademlia.Kademlia;
|
import kademlia.KademliaNode;
|
||||||
import kademlia.message.SimpleMessage;
|
import kademlia.message.SimpleMessage;
|
||||||
import kademlia.node.NodeId;
|
import kademlia.node.NodeId;
|
||||||
import kademlia.message.SimpleReceiver;
|
import kademlia.message.SimpleReceiver;
|
||||||
@ -19,8 +19,8 @@ public class SimpleMessageTest
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Kademlia kad1 = new Kademlia("Joshua", new NodeId("12345678901234567890"), 7574);
|
KademliaNode kad1 = new KademliaNode("Joshua", new NodeId("12345678901234567890"), 7574);
|
||||||
Kademlia kad2 = new Kademlia("Crystal", new NodeId("12345678901234567891"), 7572);
|
KademliaNode kad2 = new KademliaNode("Crystal", new NodeId("12345678901234567891"), 7572);
|
||||||
|
|
||||||
kad1.getServer().sendMessage(kad2.getNode(), new SimpleMessage("Some Message"), new SimpleReceiver());
|
kad1.getServer().sendMessage(kad2.getNode(), new SimpleMessage("Some Message"), new SimpleReceiver());
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user