use of i2p.bote.packet.dht.IndexPacketDeleteRequest 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.IndexPacketDeleteRequest in project i2p.i2p-bote by i2p.
the class IndexPacketFolder method storeAndCreateDeleteRequest.
@Override
public DeleteRequest storeAndCreateDeleteRequest(DhtStorablePacket packetToStore) {
if (!(packetToStore instanceof IndexPacket))
throw new IllegalArgumentException("Invalid packet type: " + packetToStore.getClass().getSimpleName() + "; this folder only stores packets of type " + IndexPacket.class.getSimpleName() + ".");
IndexPacket indexPacketToStore = (IndexPacket) packetToStore;
// set the time stamps before merging so existing ones don't change
setTimeStamps(indexPacketToStore);
// use super.retrieve() because we don't want to delete time stamps here
DhtStorablePacket existingPacket = super.retrieve(packetToStore.getDhtKey());
// make a Delete Request that contains any known-to-be-deleted DHT keys from the store request
String delFileName = getDeletionFileName(packetToStore.getDhtKey());
DeletionInfoPacket delInfo = createDelInfoPacket(delFileName);
IndexPacketDeleteRequest delRequest = null;
if (delInfo != null) {
delRequest = null;
for (IndexPacketEntry entry : indexPacketToStore) {
DeletionRecord delRecord = delInfo.getEntry(entry.emailPacketKey);
if (delRecord != null) {
// leave delRequest null until a DeletionRecord is found
if (delRequest == null)
delRequest = new IndexPacketDeleteRequest(indexPacketToStore.getDhtKey());
delRequest.put(delRecord.dhtKey, delRecord.delAuthorization);
}
}
}
// remove deleted entries from indexPacketToStore so they are not re-stored
if (delInfo != null && !delInfo.isEmpty())
for (DeletionRecord delRecord : delInfo) indexPacketToStore.remove(delRecord.dhtKey);
// The resulting packet may be too big for a datagram but we don't split it until a peer asks for it.
if (existingPacket instanceof IndexPacket)
indexPacketToStore = new IndexPacket(indexPacketToStore, (IndexPacket) existingPacket);
else if (existingPacket != null)
log.error("Packet of type " + existingPacket.getClass().getSimpleName() + " found in IndexPacketFolder.");
// don't merge, but overwrite
super.store(indexPacketToStore);
return delRequest;
}
use of i2p.bote.packet.dht.IndexPacketDeleteRequest in project i2p.i2p-bote by i2p.
the class IndexPacketFolder method packetReceived.
@Override
public void packetReceived(CommunicationPacket packet, Destination sender, long receiveTime) {
if (packet instanceof IndexPacketDeleteRequest) {
IndexPacketDeleteRequest delRequest = (IndexPacketDeleteRequest) packet;
process(delRequest);
}
}
use of i2p.bote.packet.dht.IndexPacketDeleteRequest in project i2p.i2p-bote by i2p.
the class CheckEmailTask method call.
/**
* Returns <code>true</code> if a new email was created in the inbox as a result
* of receiving an email packet.
*/
@Override
public Boolean call() throws InterruptedException, ExecutionException, TimeoutException, GeneralSecurityException {
log.debug("Querying the DHT for index packets with key " + identity.getHash());
// Use findAll rather than findOne because some peers might have an incomplete set of
// Email Packet keys, and because we want to send IndexPacketDeleteRequests to all of them.
DhtResults indexPacketResults = dht.findAll(identity.getHash(), IndexPacket.class);
if (indexPacketResults.isEmpty())
return false;
Collection<IndexPacket> indexPackets = getIndexPackets(indexPacketResults.getPackets());
IndexPacket mergedPacket = new IndexPacket(indexPackets);
log.debug("Found " + mergedPacket.getNumEntries() + " Email Packet keys in " + indexPacketResults.getNumResults() + " Index Packets.");
newEmail = false;
indexPacketDeleteRequest = new IndexPacketDeleteRequest(identity.getHash());
Collection<Future<?>> futureResults = new ArrayList<Future<?>>();
ExecutorService executor = Executors.newFixedThreadPool(MAX_THREADS, EMAIL_PACKET_TASK_THREAD_FACTORY);
for (IndexPacketEntry entry : mergedPacket) {
Runnable task = new EmailPacketTask(entry.emailPacketKey);
futureResults.add(executor.submit(task));
}
// end all EmailPacketTask threads when tasks are finished
executor.shutdown();
// wait until all EmailPacketTasks are done
try {
for (Future<?> result : futureResults) result.get(1, TimeUnit.HOURS);
} catch (InterruptedException e) {
executor.shutdownNow();
Thread.currentThread().interrupt();
throw new InterruptedException("EmailPacketTask interrupted");
}
// delete index packets if all EmailPacketTasks finished without throwing an exception
Set<Destination> indexPacketPeers = indexPacketResults.getPeers();
if (indexPacketDeleteRequest.getNumEntries() > 0)
send(indexPacketDeleteRequest, indexPacketPeers);
return newEmail;
}
use of i2p.bote.packet.dht.IndexPacketDeleteRequest in project i2p.i2p-bote by i2p.
the class IndexPacketFolder method process.
/**
* Deletes index packet entries.
* @param delRequest An instance of {@link IndexPacketDeleteRequest}
*/
@Override
public synchronized void process(DeleteRequest delRequest) {
log.debug("Processing delete request: " + delRequest);
if (!(delRequest instanceof IndexPacketDeleteRequest))
log.error("Invalid type of delete request for IndexPacketFolder: " + delRequest.getClass());
IndexPacketDeleteRequest indexPacketDelRequest = (IndexPacketDeleteRequest) delRequest;
Hash destHash = indexPacketDelRequest.getEmailDestHash();
DhtStorablePacket storedPacket = retrieve(destHash);
if (storedPacket instanceof IndexPacket) {
IndexPacket indexPacket = (IndexPacket) storedPacket;
Collection<Hash> keysToDelete = indexPacketDelRequest.getDhtKeys();
for (Hash keyToDelete : keysToDelete) {
// verify
Hash verificationHash = indexPacket.getDeleteVerificationHash(keyToDelete);
if (verificationHash == null)
log.debug("Email packet key " + keyToDelete + " from IndexPacketDeleteRequest not found in index packet for destination " + destHash);
else {
UniqueId delAuthorization = indexPacketDelRequest.getDeleteAuthorization(keyToDelete);
boolean valid = Util.isDeleteAuthorizationValid(verificationHash, delAuthorization);
if (valid)
remove(indexPacket, keyToDelete, delAuthorization);
else
log.debug("Invalid delete verification hash in IndexPacketDeleteRequest. Should be: <" + verificationHash.toBase64() + ">");
}
}
} else if (storedPacket != null)
log.debug("IndexPacket expected for DHT key <" + destHash + ">, found " + storedPacket.getClass().getSimpleName());
}
Aggregations