Added javadoc to DHT.java

This commit is contained in:
Monsterovich 2023-10-18 01:47:45 +02:00
parent 054da4c49f
commit 3c72aae671

View file

@ -127,7 +127,7 @@ public class DHT implements Runnable {
}
/**
* Schedule a DHT ping
* Schedule a DHT ping.
*
* @param seconds poll in <code>secongs</codee> seconds
*/
@ -143,20 +143,37 @@ public class DHT implements Runnable {
}
}
/**
* Stops the DHT receiving thread, which is responsible for listening to incoming DHT packets.
* This method sets the receivingThreadRunning flag to false, waits for the thread to finish,
* and then closes the DatagramSocket used for receiving.
*/
public void stopDHTReceivingThread() {
receivingThreadRunning = false;
try {
receivingThread.join();
} catch (Exception ex) {
ex.printStackTrace(); // TODO
ex.printStackTrace();
}
dSock.close();
}
/**
* Calculates the unsigned XOR distance between the `searchIDInt` and the ID of a contact.
*
* @param c The contact for which the distance is calculated.
* @return The unsigned XOR distance as a BigInteger.
*/
private BigInteger searchDist(Contact c) {
return unsigned(searchIDInt.xor(c.getId()));
}
/**
* Converts a signed BigInteger to its unsigned equivalent.
*
* @param i The signed BigInteger to convert to unsigned.
* @return The equivalent unsigned BigInteger.
*/
public static BigInteger unsigned(BigInteger i) {
if (i.signum() < 0) {
return MASK.add(i);
@ -166,7 +183,7 @@ public class DHT implements Runnable {
}
/**
* Calculate a hash for the network, using the pubkicKey of the net
* Calculate a hash for the network, using the publicKey of the net.
*
* @param maxLen length of the hash
* @return the hash
@ -182,6 +199,12 @@ public class DHT implements Runnable {
return result;
}
/**
* Sends a ping request to a specified address in the DHT network.
*
* @param addr The address to which the ping request is sent.
* @throws IOException If there is an I/O error while sending the ping request.
*/
private void ping(SocketAddress addr) throws IOException {
BencodeMap m = new BencodeMap();
m.put(new BencodeString("t"), new BencodeString("ping"));
@ -196,6 +219,12 @@ public class DHT implements Runnable {
Logger.getLogger("").log(Level.INFO, "Using DHT bootstrap node: " + addr.toString());
}
/**
* Requests the list of peers for a specific info hash from a contact in the DHT network.
*
* @param c The contact to request peers from.
* @throws IOException If there is an I/O error while sending the request packet.
*/
private void getPeers(Contact c) throws IOException {
BencodeMap m = new BencodeMap();
m.put(new BencodeString("t"), new BencodeString("get_peers"));
@ -210,6 +239,13 @@ public class DHT implements Runnable {
sendPacket(c.getAddr(), m);
}
/**
* Announces the presence of a peer to the DHT network.
*
* @param c The contact representing the target peer.
* @param token The token required for the announcement.
* @throws IOException If there is an I/O error while sending the announcement packet.
*/
private synchronized void announcePeer(Contact c, BencodeString token) throws IOException {
if (token == null) {
return;
@ -230,6 +266,10 @@ public class DHT implements Runnable {
sendPacket(c.getAddr(), m);
}
/**
* Performs bootstrap operation by pinging DHT bootstrap nodes to join the DHT network.
* Uses a list of predefined DHT bootstrap nodes for initialization.
*/
private void bootstrap() {
try {
for (String dhtNode : DHT_BOOTSTRAP_NODES) {
@ -241,6 +281,11 @@ public class DHT implements Runnable {
}
}
/**
* This method processes peers in the DHT to find the best contacts given certain conditions.
* These conditions include limits on the number of "bad" contacts (those that are down or unavailable),
* and may also consider other factors such as distance from the current node (see peerQueue).
*/
private void processPeers() {
try {
Vector<Contact> best = new Vector<Contact>();
@ -249,8 +294,8 @@ public class DHT implements Runnable {
while (best.size() < MAX_GOOD && null != (contact = peerQueue.poll())) {
if (!best.contains(contact) && getBad(contact) < MAX_BAD) {
best.add(contact);
//System.out.println("best: dist: " + searchDist(c).bitLength() + " peer: " + c
// + " bad: " + getBad(c));
System.out.println("best: dist: " + searchDist(contact).bitLength() + " peer: " + contact
+ " bad: " + getBad(contact));
}
}
}
@ -264,6 +309,13 @@ public class DHT implements Runnable {
}
}
/**
* Sends a BencodeObject as a packet to the specified SocketAddress.
*
* @param addr The destination SocketAddress to send the packet to.
* @param o The BencodeObject to be sent as a packet.
* @throws IOException If an I/O error occurs during the sending process.
*/
private void sendPacket(SocketAddress addr, BencodeObject o) throws IOException {
ByteArrayOutputStream out = new ByteArrayOutputStream();
o.write(out);
@ -272,10 +324,21 @@ public class DHT implements Runnable {
dSock.send(p);
}
/**
* Removes a contact from the list of bad peers, marking it as a good peer.
*
* @param c The contact to be marked as a good peer.
*/
private void makeGood(Contact c) {
peerBad.remove(c);
}
/**
* Retrieves the bad count for a given contact, indicating its quality as a peer.
*
* @param c The contact for which the bad count is retrieved.
* @return The bad count for the contact (0 if no bad count is recorded).
*/
private int getBad(Contact c) {
Integer i = peerBad.get(c);
if (i == null) {
@ -284,10 +347,21 @@ public class DHT implements Runnable {
return i;
}
/**
* Increases the bad count for a contact, marking it as a potentially bad peer.
*
* @param c The contact to be marked as a bad peer.
*/
private void makeBad(Contact c) {
peerBad.put(c, getBad(c) + 1);
}
/**
* Adds a contact to the peer queue and optionally marks it as a good peer.
*
* @param c The contact to be added to the peer queue.
* @param good Indicates whether the contact should be marked as a good peer.
*/
private void addQueue(Contact c, boolean good) {
if (!peerQueue.contains(c)) {
peerQueue.add(c);
@ -297,6 +371,11 @@ public class DHT implements Runnable {
}
}
/**
* Processes an incoming DatagramPacket containing Bencode-encoded data.
*
* @param packet The DatagramPacket containing the Bencode-encoded data.
*/
private void receivePacket(DatagramPacket packet) {
try {
BencodeObject object = Bencode.parseBencode(new ByteArrayInputStream(packet.getData(), 0, packet.getLength()));
@ -322,15 +401,29 @@ public class DHT implements Runnable {
// System.out.println();
}
} catch (IOException ex) {
ex.printStackTrace(); // TODO
ex.printStackTrace();
}
}
/**
* Handles a ping response received as a BencodeMap.
*
* @param packet The DatagramPacket containing the ping response data.
* @param response The BencodeMap representing the ping response.
* @throws IOException If there is an I/O error during the handling process.
*/
private void handlePing(DatagramPacket packet, BencodeMap response) throws IOException {
BencodeString nodeId = (BencodeString) response.get(new BencodeString("id"));
addQueue(new Contact(nodeId.getBytes(), packet.getSocketAddress()), true);
}
/**
* Handles a get_peers response received as a BencodeMap, processing information about peers and tokens.
*
* @param packet The DatagramPacket containing the get_peers response data.
* @param response The BencodeMap representing the get_peers response.
* @throws IOException If there is an I/O error during the handling process.
*/
private void handlePeers(DatagramPacket packet, BencodeMap response) throws IOException {
BencodeString nodeId = (BencodeString) response.get(new BencodeString("id"));
Contact remotePeer = new Contact(nodeId.getBytes(), packet.getSocketAddress());
@ -412,6 +505,13 @@ public class DHT implements Runnable {
}
}
/**
* Runs a thread to continuously receive UDP packets and process them.
*
* This method runs a thread that listens for UDP packets, processes each packet,
* and handles any exceptions related to I/O operations. The thread runs until
* the flag `receivingThreadRunning` is set to false.
*/
private void runReceivingThread() {
try {
byte[] buf = new byte[PACKET_LEN];
@ -421,7 +521,7 @@ public class DHT implements Runnable {
receivePacket(packet);
}
} catch (IOException iOException) {
iOException.printStackTrace(); // TODO
iOException.printStackTrace();
}
}
}