use of i2p.bote.packet.dht.DhtStorablePacket in project i2p.i2p-bote by i2p.
the class KademliaDHT method getDhtResults.
/**
* Returns all <code>DhtStorablePacket</code> packets that have been received as a response to a send batch,
* plus <code>localResult</code> if it is non-<code>null</code>.
* @param batch
* @param localResult
*/
private DhtResults getDhtResults(PacketBatch batch, DhtStorablePacket localResult) {
Map<Destination, DataPacket> responses = batch.getResponses();
DhtResults results = new DhtResults();
for (Entry<Destination, DataPacket> result : responses.entrySet()) {
DataPacket packet = result.getValue();
if (packet instanceof DhtStorablePacket)
results.put(result.getKey(), (DhtStorablePacket) packet);
}
int totalResponses = responses.size();
if (localResult != null) {
results.put(localDestination, localResult);
totalResponses++;
}
results.setTotalResponses(totalResponses);
return results;
}
use of i2p.bote.packet.dht.DhtStorablePacket in project i2p.i2p-bote by i2p.
the class ReplicateThread method replicate.
private void replicate() throws InterruptedException {
log.debug("Replicating DHT data...");
replicationRunning = true;
// refresh peers close to the local destination
ClosestNodesLookupTask lookupTask = new ClosestNodesLookupTask(localDestination.calculateHash(), sendQueue, i2pReceiver, bucketManager);
List<Destination> closestNodes = lookupTask.call();
closestNodes.remove(localDestination);
int numReplicated = 0;
int numSkipped = 0;
// If a peer responds with a delete request, replicate the delete request instead.
for (DhtStorageHandler dhtStore : dhtStores) for (Iterator<? extends DhtStorablePacket> packetIterator = dhtStore.individualPackets(); packetIterator.hasNext(); ) {
DhtStorablePacket packet = packetIterator.next();
Hash dhtKey = packet.getDhtKey();
if (!keysToSkip.contains(dhtKey)) {
StoreRequest request = new StoreRequest(packet);
List<Destination> closestPeers = bucketManager.getClosestPeers(dhtKey, KademliaConstants.K);
for (Destination peer : closestPeers) {
// Send the store request and give the peer time to respond with a delete request
sendQueue.send(request, peer).await(SEND_TIMEOUT_MINUTES, TimeUnit.MINUTES);
TimeUnit.SECONDS.sleep(WAIT_TIME_SECONDS);
// If we received a delete request for the DHT item, notify the other close peers
DeleteRequest delRequest = receivedDeleteRequests.get(dhtKey);
if (delRequest != null) {
// KademliaDHT handles the delete request for local data, but we forward the
// request to the other nodes close to the DHT key.
// Note that the delete request contains only one entry, see packetReceived()
sendDeleteRequest(delRequest, closestPeers, peer);
break;
}
}
numReplicated++;
} else
numSkipped++;
}
keysToSkip.clear();
replicationRunning = false;
receivedDeleteRequests.clear();
log.debug("Replication finished. Replicated " + numReplicated + " packets, skipped: " + numSkipped);
}
use of i2p.bote.packet.dht.DhtStorablePacket in project i2p.i2p-bote by i2p.
the class RelayPacketHandler method packetReceived.
@Override
public void packetReceived(CommunicationPacket packet, Destination sender, long receiveTime) {
if (packet instanceof RelayRequest && dht.isReady()) {
RelayRequest relayRequest = (RelayRequest) packet;
CommunicationPacket payload;
try {
payload = relayRequest.getStoredPacket(i2pSession);
} catch (DataFormatException e) {
log.error("Invalid RelayRequest received from peer " + Util.toBase32(sender), e);
return;
} catch (MalformedPacketException e) {
log.error("Invalid RelayRequest received from peer " + Util.toBase32(sender), e);
return;
}
log.debug("Received a relay request, payload: " + payload);
if (payload instanceof RelayRequest) {
log.debug("Relay packet is of type " + payload.getClass().getSimpleName() + ", storing it in the relay packet folder.");
relayPacketFolder.add((RelayRequest) payload);
confirm(sender, relayRequest);
} else if (payload instanceof StoreRequest) {
log.debug("Relay packet is of type " + payload.getClass().getSimpleName() + ", storing it in the DHT.");
final DhtStorablePacket dhtPacket = ((StoreRequest) payload).getPacketToStore();
// do dht.store() in a separate thread so we don't block the notifier thread
dhtTaskExecutor.submit(new Runnable() {
@Override
public void run() {
try {
dht.store(dhtPacket);
log.debug("Finished storing DHT packet: " + dhtPacket);
} catch (InterruptedException e) {
log.debug("Interrupted while storing packet in the DHT.");
} catch (DhtException e) {
log.error("Error storing packet in the DHT: " + dhtPacket, e);
}
}
});
confirm(sender, relayRequest);
} else
log.error("Don't know how to handle relay packet of type " + payload.getClass());
}
}
use of i2p.bote.packet.dht.DhtStorablePacket in project i2p.i2p-bote by i2p.
the class IndexPacketFolderTest method testProcessDeleteRequest.
@Test
public void testProcessDeleteRequest() throws GeneralSecurityException, MalformedPacketException, PasswordException {
IndexPacketFolder folder = new IndexPacketFolder(folderDir);
// create another packet with the same destination as emailPacket1
EncryptedEmailPacket emailPacket3 = new EncryptedEmailPacket(unencryptedPacket2, destination1);
IndexPacket indexPacket = new IndexPacket(destination1);
indexPacket.put(emailPacket1);
indexPacket.put(emailPacket3);
folder.store(indexPacket);
assertEquals("Folder should have exactly one element!", 1, folder.getElements().size());
// add two entries and delete them via delete requests
Hash dest1Hash = destination1.getHash();
IndexPacketDeleteRequest delRequest = new IndexPacketDeleteRequest(dest1Hash);
Hash dhtKey1 = emailPacket1.getDhtKey();
Hash dhtKey3 = emailPacket3.getDhtKey();
delRequest.put(dhtKey1, unencryptedPacket1.getDeleteAuthorization());
delRequest.put(dhtKey3, unencryptedPacket2.getDeleteAuthorization());
folder.process(delRequest);
DhtStorablePacket storedPacket = folder.retrieve(dest1Hash);
assertTrue(storedPacket instanceof IndexPacket);
assertEquals("The index packet should have no entries!", 0, ((IndexPacket) storedPacket).getNumEntries());
// verify that there is one deletion file containing two entries
File[] files = folder.getStorageDirectory().listFiles(new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
return name.startsWith("DEL_");
}
});
assertEquals(1, files.length);
DataPacket dataPacket = DataPacket.createPacket(files[0]);
assertTrue(dataPacket instanceof DeletionInfoPacket);
DeletionInfoPacket delInfoPacket = (DeletionInfoPacket) dataPacket;
Iterator<DeletionRecord> delPacketIterator = delInfoPacket.iterator();
assertTrue("DeletionInfoPacket has no elements!", delPacketIterator.hasNext());
delPacketIterator.next();
assertTrue("DeletionInfoPacket has less than one element!", delPacketIterator.hasNext());
delPacketIterator.next();
assertFalse("DeletionInfoPacket has more than two elements!", delPacketIterator.hasNext());
// verify that the two deletion records match the DHT keys and auth keys of the deleted packets
DeleteRequest newDelRequest = folder.storeAndCreateDeleteRequest(indexPacket);
assertTrue(newDelRequest instanceof IndexPacketDeleteRequest);
IndexPacketDeleteRequest newIndexPacketDelRequest = (IndexPacketDeleteRequest) newDelRequest;
assertEquals(newIndexPacketDelRequest.getDeleteAuthorization(dhtKey1), unencryptedPacket1.getDeleteAuthorization());
assertEquals(newIndexPacketDelRequest.getDeleteAuthorization(dhtKey3), unencryptedPacket2.getDeleteAuthorization());
}
use of i2p.bote.packet.dht.DhtStorablePacket in project i2p.i2p-bote by i2p.
the class I2PBote method lookupInDirectory.
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;
}
Aggregations