@Override public IndexPacket next() { if (currentPacketIterator==null || !currentPacketIterator.hasNext()) { currentPacket = bigPackets.next(); currentPacketIterator = currentPacket.iterator(); } IndexPacketEntry entry = currentPacketIterator.next(); IndexPacket indexPacket = new IndexPacket(currentPacket.getDhtKey()); indexPacket.put(entry); return indexPacket; }
/** * Adds an entry to the <code>IndexPacket</code>. If an entry with the same DHT key * exists in the packet already, nothing happens. * @param entry */ public void put(IndexPacketEntry entry) { if (contains(entry.emailPacketKey)) return; entries.add(entry); }
/** * Deletes an entry from an {@link IndexPacket} and saves the packet to disk. * @param indexPacket * @param emailPacketKey The entry to delete */ private synchronized void remove(IndexPacket indexPacket, Hash emailPacketKey, UniqueId delAuthorization) { log.debug("Removing DHT key " + emailPacketKey + " from Index Packet for Email Dest " + indexPacket.getDhtKey()); indexPacket.remove(emailPacketKey); // DEL_FILE_PREFIX + getFilename(indexPacket) String delFileName = getDeletionFileName(indexPacket.getDhtKey()); addToDeletedPackets(delFileName, emailPacketKey, delAuthorization); super.store(indexPacket); // don't merge, but overwrite the file with the entry removed }
/** * Merges the DHT keys of multiple index packets into one big index packet.<br/> * The Email Destination of this packet is set to that of the first input packet. * @param indexPackets * @throws IllegalArgumentException If an empty <code>Collection</code> or <code>null</code> was passed in */ public IndexPacket(Collection<IndexPacket> indexPackets) { if (indexPackets==null || indexPackets.isEmpty()) throw new IllegalArgumentException("This method must be invoked with at least one index packet."); IndexPacket firstPacket = indexPackets.iterator().next(); destinationHash = firstPacket.getDhtKey(); entries = new ArrayList<IndexPacketEntry>(); for (IndexPacket packet: indexPackets) { for (IndexPacketEntry entry: packet) put(entry); } }
@Override public Collection<? extends DataPacket> split() { if (isTooBig()) { int bytesPerEntry = entries.get(0).emailPacketKey.toByteArray().length + entries.get(0).delVerificationHash.toByteArray().length + 4; // see toByteArray() List<IndexPacket> subpackets = new ArrayList<IndexPacket>(); IndexPacket currentSubpacket = new IndexPacket(destinationHash); for (IndexPacketEntry entry: entries) { if (currentSubpacket.getSize()+bytesPerEntry > MAX_DATAGRAM_SIZE) { subpackets.add(currentSubpacket); currentSubpacket = new IndexPacket(destinationHash); } currentSubpacket.put(entry); } subpackets.add(currentSubpacket); return subpackets; } else return Collections.singleton(this); } }
@Test public void testMergePackets() { for (int i=0; i<8; i+=2) { IndexPacket mergedPacket = new IndexPacket(indexPacket1, indexPacket2); // Verify that the merged packet and the two original packets all have the same email destination key assertEquals(mergedPacket.getDhtKey(), indexPacket1.getDhtKey()); assertEquals(mergedPacket.getDhtKey(), indexPacket2.getDhtKey()); // Verify that the merged packet contains the email packet keys from the original two packets assertEquals(5, mergedPacket.getNumEntries()); for (IndexPacketEntry entry: indexPacket1) assertTrue("Merged packet does not contain key: " + entry.emailPacketKey, mergedPacket.contains(entry.emailPacketKey)); for (IndexPacketEntry entry: indexPacket2) assertTrue("Merged packet does not contain key: " + entry.emailPacketKey, mergedPacket.contains(entry.emailPacketKey)); } }
IndexPacket indexPacket = new IndexPacket(destination1); indexPacket.put(emailPacket1); long expirationTime1 = cutoffTime - 3*1000; setStoreTime(indexPacket, emailPacket1.getDhtKey(), expirationTime1); assertEquals(1, indexPacket.getNumEntries()); folder.store(indexPacket); assertEquals(1, folder.getElements().size()); assertEquals(1, folder.getElements().get(0).getNumEntries()); assertEquals(expirationTime1/1000L, folder.getElements().get(0).iterator().next().storeTime/1000L); // round to seconds indexPacket.put(emailPacket2); long expirationTime2 = cutoffTime + 3*1000; setStoreTime(indexPacket, emailPacket2.getDhtKey(), expirationTime2); assertEquals(2, indexPacket.getNumEntries()); folder.store(indexPacket); assertEquals(1, folder.getElements().size()); assertEquals(1, folder.iterator().next().getNumEntries()); assertEquals(0, folder.iterator().next().getNumEntries());
@Before public void setUp() throws Exception { identity = new EmailIdentity("5LqFf~U3aLbJfbfTVtp7kXLPFoeIFo4l8WTg1Wi52bWoxAYaevVVBtR9AvKqy1YmZHbnOIcu59~2X6wMmi6SveljmvAeTc5YEHvfIRrJhnxqjaC4IczYKXfUdrXfaeVEKMQ~PKuvhINh~EhlJUQne0NZQ~S6QAGfUAu83mMoBTVaz0eoUnAzySxbSf~NpxUoK-H6iULsFekmYfaz-yq8cxPFy62LyylTRMGFFwb9is7E~mFnV6Fa0iGSDJvpFfYV29efVUjxiW9JT5T0HwgdaDB4ssSNr0-hthigJmB7zLXOJ8F1gxi3qCfTX9SiGMrZ9KZsOLc7Qs7Iix3ECqesfGTIs9n5G1qnfZriyc1FZdylCMQcnq5QvTITV-Cil0XrU1csV5CEFYEUGfGdLP1xP2SCZr8KJwOI0xfUnkkVnNPc2y~ZGhqxpHeIcnZCpScW-p81vFvTe5fwvEVWixgk6MlFKYyQku28brQ19Tz5tsIH3tUvl4cqGzLVQUbi3cODAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAmogzaNWx7p~GTVQxl1JzqcOTyRfELoxqEGS5BowqPe4FNa3Bo-diEcU3k90Cx5MX"); // Make an IndexPacket with 3 entries emailPacket1 = makeEmailPacket("abc"); emailPacket2 = makeEmailPacket("abcd"); emailPacket3 = makeEmailPacket("abcde"); indexPacket1 = new IndexPacket(identity); indexPacket1.put(emailPacket1); indexPacket1.put(emailPacket2); indexPacket1.put(emailPacket3); // Make an IndexPacket with 2 entries emailPacket4 = makeEmailPacket("abcdef"); emailPacket5 = makeEmailPacket("abcdefg"); indexPacket2 = new IndexPacket(identity); indexPacket2.put(emailPacket4); indexPacket2.put(emailPacket5); }
delRequest = new IndexPacketDeleteRequest(indexPacketToStore.getDhtKey()); delRequest.put(delRecord.dhtKey, delRecord.delAuthorization); indexPacketToStore.remove(delRecord.dhtKey); indexPacketToStore = new IndexPacket(indexPacketToStore, (IndexPacket)existingPacket); else if (existingPacket != null) log.error("Packet of type " + existingPacket.getClass().getSimpleName() + " found in IndexPacketFolder.");
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()); DhtStorablePacket storedPacket = folder.retrieve(dest1Hash); assertTrue(storedPacket instanceof IndexPacket); assertEquals("The index packet should have no entries!", 0, ((IndexPacket)storedPacket).getNumEntries());
/** * Does not add a Deletion Record, just deletes the file. */ @Override public synchronized void deleteExpired() { long currentTime = System.currentTimeMillis(); for (IndexPacket indexPacket: this) { boolean removed = false; // true if at least one entry was removed synchronized(indexPacket) { Iterator<IndexPacketEntry> iterator = indexPacket.iterator(); while (iterator.hasNext()) { IndexPacketEntry entry = iterator.next(); if (currentTime > entry.storeTime + EXPIRATION_TIME_MILLISECONDS) { log.debug("Deleting expired index packet entry: file=<" + getFilename(indexPacket.getDhtKey()) + ">, emailPktKey=" + entry.emailPacketKey.toBase64()); iterator.remove(); removed = true; } } if (removed) super.store(indexPacket); // don't merge, but overwrite the file with the entry/entries removed } } }
@Test public void testRemoveKey() { assertEquals(3, indexPacket1.getNumEntries()); // Try to remove a key that doesn't exist in the packet indexPacket1.remove(emailPacket4.getDhtKey()); assertEquals(3, indexPacket1.getNumEntries()); // Remove a key that does exist in the packet indexPacket1.remove(emailPacket1.getDhtKey()); assertEquals(2, indexPacket1.getNumEntries()); } }
IndexPacket mergedPacket = new IndexPacket(indexPackets); log.debug("Found " + mergedPacket.getNumEntries() + " Email Packet keys in " + indexPacketResults.getNumResults() + " Index Packets.");
/** * Verifies that the arrays are the right length * @throws IllegalAccessException * @throws NoSuchFieldException * @throws IllegalArgumentException * @throws SecurityException */ @Test public void testToByteArray() throws SecurityException, IllegalArgumentException, NoSuchFieldException, IllegalAccessException { // test the first index packet int arrayLength1 = indexPacket1.toByteArray().length; int expectedLength1 = 2 + Hash.HASH_LENGTH + 4 + indexPacket1.getNumEntries() * (2*Hash.HASH_LENGTH+4); assertEquals(expectedLength1, arrayLength1); // test the second index packet int arrayLength2 = indexPacket2.toByteArray().length; int expectedLength2 = 2 + Hash.HASH_LENGTH + 4 + indexPacket2.getNumEntries() * (2*Hash.HASH_LENGTH+4); assertEquals(expectedLength2, arrayLength2); }
@Test public void testToByteArrayAndBack() throws GeneralSecurityException { IndexPacket newPacket1 = new IndexPacket(indexPacket1.toByteArray()); assertTrue("The two packets differ!", equal(indexPacket1, newPacket1)); IndexPacket newPacket2 = new IndexPacket(indexPacket2.toByteArray()); assertTrue("The two packets differ!", equal(indexPacket2, newPacket2)); }
public void put(Collection<EncryptedEmailPacket> emailPackets) { for (EncryptedEmailPacket emailPacket: emailPackets) { Hash emailPacketKey = emailPacket.getDhtKey(); Hash delVerificationHash = emailPacket.getDeleteVerificationHash(); IndexPacketEntry entry = new IndexPacketEntry(emailPacketKey, delVerificationHash); put(entry); } }
IndexPacket indexPacket = new IndexPacket(currentPacket.getDhtKey()); indexPacket.put(entry); return indexPacket;
@Override public boolean hasNext() { if (currentPacketIterator!=null && currentPacketIterator.hasNext()) return true; while (bigPackets.hasNext()) { currentPacket = bigPackets.next(); currentPacketIterator = currentPacket.iterator(); if (currentPacketIterator.hasNext()) return true; } return false; }
if (packetA.getNumEntries() != packetB.getNumEntries()) return false;
/** * Tests if the <code>IndexPacket</code> contains a given DHT key. * @param emailPacketKey * @return <code>true</code> if the packet containes the DHT key, <code>false</code> otherwise. */ public boolean contains(Hash emailPacketKey) { return getEntry(emailPacketKey) != null; }