private void refresh(KBucket bucket) throws InterruptedException { Hash key = createRandomHash(bucket.getStartId(), bucket.getEndId()); getClosestNodes(key); }
@Override public DhtResults findAll(Hash key, Class<? extends DhtStorablePacket> dataType) throws InterruptedException { return find(key, dataType, true); }
public DhtPeerStats getDhtStats(DhtPeerStatsRenderer renderer) { if (dht == null) return null; else return dht.getPeerStats(renderer); }
@Override public void run() { i2pReceiver.addPacketListener(this); bootstrap(); replicateThread.start(); while (!Thread.interrupted()) { try { if (bucketManager.getUnlockedPeerCount() == 0) { log.info("All peers are gone. Re-bootstrapping."); bootstrap(); } refreshOldBuckets(); TimeUnit.MINUTES.sleep(1); } catch (InterruptedException e) { break; } catch (RuntimeException e) { // catch unexpected exceptions to keep the thread running log.error("Exception caught in KademliaDHT loop", e); } } replicateThread.interrupt(); i2pReceiver.removePacketListener(this); writePeersSorted(peerFile); log.debug("KademliaDHT thread exiting."); } }
@Override public void store(DhtStorablePacket packet) throws DhtException, InterruptedException { Hash key = packet.getDhtKey(); log.info("Looking up nodes to store a " + packet.getClass().getSimpleName() + " with key " + key); List<Destination> closeNodes = getClosestNodes(key); if (closeNodes.isEmpty()) throw new DhtException("Cannot store packet because no storage nodes found."); // store on local node if appropriate if (!closeNodes.contains(localDestination)) if (closeNodes.size()<KademliaConstants.K || isCloser(localDestination, closeNodes.get(0), key)) closeNodes.add(localDestination); log.info("Storing a " + packet.getClass().getSimpleName() + " with key " + key + " on " + closeNodes.size() + " nodes"); PacketBatch batch = new PacketBatch(); for (Destination node: closeNodes) if (localDestination.equals(node)) storeLocally(packet, null); else { StoreRequest storeRequest = new StoreRequest(packet); // use a separate packet id for each request batch.putPacket(storeRequest, node); } sendQueue.send(batch); batch.awaitSendCompletion(); // TODO awaitAllResponses, repeat if necessary sendQueue.remove(batch); }
private DhtResults find(Hash key, Class<? extends DhtStorablePacket> dataType, boolean exhaustive) throws InterruptedException { final Collection<Destination> closeNodes = getClosestNodes(key); log.info("Querying localhost + " + closeNodes.size() + " peers for data type " + dataType.getSimpleName() + ", Kademlia key " + key); DhtStorablePacket localResult = findLocally(key, dataType); return getDhtResults(batch, localResult);
dht = new KademliaDHT(sendQueue, dispatcher, configuration.getDhtPeerFile(), (DhtPeerSource) seedless); backgroundThreads.add(dht); dht.setStorageHandler(EncryptedEmailPacket.class, emailDhtStorageFolder); dht.setStorageHandler(IndexPacket.class, indexPacketDhtStorageFolder); dht.setStorageHandler(Contact.class, directoryDhtFolder);
public Contact lookupInDirectory(String name) throws InterruptedException { Hash key = EmailIdentity.calculateHash(name); if(null == dht){ return null; } DhtResults results = dht.findOne(key, Contact.class); if (!results.isEmpty()) { DhtStorablePacket packet = results.getPackets().iterator().next(); if (packet instanceof Contact) { Contact contact = (Contact)packet; try { if (contact.verify()) return contact; } catch (GeneralSecurityException e) { log.error("Can't verify Contact", e); } } } return null; }
@Override public UniqueId findDeleteAuthorizationKey(Hash dhtKey, Hash verificationHash) throws InterruptedException { final Collection<Destination> closeNodes = getClosestNodes(dhtKey); log.info("Querying " + closeNodes.size() + " peers with DeletionQueries for Kademlia key " + dhtKey);
private void refresh(BucketSection section) throws InterruptedException { Hash key = createRandomHash(section.getStart(), section.getEnd()); getClosestNodes(key); }
@Override public DhtResults findOne(Hash key, Class<? extends DhtStorablePacket> dataType) throws InterruptedException { return find(key, dataType, false); }