Search in sources :

Example 1 with IndexPacket

use of i2p.bote.packet.dht.IndexPacket in project i2p.i2p-bote by i2p.

the class OutboxProcessor method sendToOne.

/**
 * Sends an {@link Email} to one recipient.
 * @param senderIdentity The sender's Email Identity, or <code>null</code> for anonymous emails
 * @param recipient
 * @param email
 * @throws MessagingException
 * @throws DhtException
 * @throws GeneralSecurityException
 * @throws PasswordException
 * @throws InterruptedException
 */
private void sendToOne(EmailIdentity senderIdentity, String recipient, Email email) throws MessagingException, DhtException, GeneralSecurityException, PasswordException, InterruptedException {
    // only used for logging
    String logSuffix = null;
    try {
        logSuffix = "Recipient = '" + recipient + "' Message ID = '" + email.getMessageID() + "'";
        log.info("Sending email: " + logSuffix);
        EmailDestination recipientDest = new EmailDestination(recipient);
        EmailIdentity.IdentityConfig identityConfig;
        if (email.isAnonymous())
            identityConfig = configuration;
        else
            identityConfig = senderIdentity.getWrappedConfig(configuration);
        int hops = identityConfig.getNumStoreHops();
        long minDelay = identityConfig.getRelayMinDelay() * 60 * 1000;
        long maxDelay = identityConfig.getRelayMaxDelay() * 60 * 1000;
        int relayRedundancy = identityConfig.getRelayRedundancy();
        int maxPacketSize = getMaxEmailPacketSize(hops);
        Collection<UnencryptedEmailPacket> emailPackets = email.createEmailPackets(senderIdentity, identities, recipient, maxPacketSize);
        IndexPacket indexPacket = new IndexPacket(recipientDest);
        EmailMetadata metadata = email.getMetadata();
        for (UnencryptedEmailPacket unencryptedPacket : emailPackets) {
            EncryptedEmailPacket emailPacket = new EncryptedEmailPacket(unencryptedPacket, recipientDest);
            send(emailPacket, hops, minDelay, maxDelay, relayRedundancy);
            indexPacket.put(emailPacket);
            metadata.addPacketInfo(recipientDest, emailPacket.getDhtKey(), emailPacket.getDeleteVerificationHash());
        }
        send(indexPacket, hops, minDelay, maxDelay, relayRedundancy);
        outbox.saveMetadata(email);
    } catch (GeneralSecurityException e) {
        log.error("Invalid recipient address. " + logSuffix, e);
        outbox.setStatus(email, new EmailStatus(Status.INVALID_RECIPIENT, recipient));
        throw e;
    } catch (MessagingException e) {
        log.error("Can't create email packets. " + logSuffix, e);
        outbox.setStatus(email, new EmailStatus(Status.ERROR_CREATING_PACKETS, e.getLocalizedMessage()));
        throw e;
    } catch (DhtException e) {
        log.error("Can't store email packet on the DHT. " + logSuffix, e);
        outbox.setStatus(email, new EmailStatus(Status.ERROR_SENDING, e.getLocalizedMessage()));
        throw e;
    } catch (IOException e) {
        log.error("Can't save metadata. " + logSuffix, e);
        outbox.setStatus(email, new EmailStatus(Status.ERROR_SAVING_METADATA, e.getLocalizedMessage()));
    }
}
Also used : MessagingException(javax.mail.MessagingException) EmailIdentity(i2p.bote.email.EmailIdentity) EncryptedEmailPacket(i2p.bote.packet.dht.EncryptedEmailPacket) GeneralSecurityException(java.security.GeneralSecurityException) EmailStatus(i2p.bote.folder.Outbox.EmailStatus) EmailMetadata(i2p.bote.email.EmailMetadata) IOException(java.io.IOException) IndexPacket(i2p.bote.packet.dht.IndexPacket) EmailDestination(i2p.bote.email.EmailDestination) UnencryptedEmailPacket(i2p.bote.packet.dht.UnencryptedEmailPacket) DhtException(i2p.bote.network.DhtException)

Example 2 with IndexPacket

use of i2p.bote.packet.dht.IndexPacket 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());
}
Also used : DhtStorablePacket(i2p.bote.packet.dht.DhtStorablePacket) IndexPacketDeleteRequest(i2p.bote.packet.dht.IndexPacketDeleteRequest) DeletionRecord(i2p.bote.packet.dht.DeletionRecord) EncryptedEmailPacket(i2p.bote.packet.dht.EncryptedEmailPacket) Hash(net.i2p.data.Hash) DataPacket(i2p.bote.packet.DataPacket) FilenameFilter(java.io.FilenameFilter) DeletionInfoPacket(i2p.bote.packet.dht.DeletionInfoPacket) IndexPacket(i2p.bote.packet.dht.IndexPacket) File(java.io.File) DeleteRequest(i2p.bote.packet.dht.DeleteRequest) IndexPacketDeleteRequest(i2p.bote.packet.dht.IndexPacketDeleteRequest) Test(org.junit.Test)

Example 3 with IndexPacket

use of i2p.bote.packet.dht.IndexPacket in project i2p.i2p-bote by i2p.

the class IndexPacketFolderTest method testCheckExpiration.

@Test
public void testCheckExpiration() throws GeneralSecurityException, InterruptedException, PasswordException {
    long cutoffTime = System.currentTimeMillis() - ExpirationListener.EXPIRATION_TIME_MILLISECONDS;
    // store a packet that expired 3 seconds ago
    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());
    // round to seconds
    assertEquals(expirationTime1 / 1000L, folder.getElements().get(0).iterator().next().storeTime / 1000L);
    // store a packet that expires in 3 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());
    // delete expired packets and check that one of the two packets got deleted
    folder.deleteExpired();
    assertEquals(1, folder.iterator().next().getNumEntries());
    // 4 seconds later, the remaining packet should have expired
    TimeUnit.SECONDS.sleep(4);
    folder.deleteExpired();
    assertEquals(0, folder.iterator().next().getNumEntries());
}
Also used : IndexPacket(i2p.bote.packet.dht.IndexPacket) Test(org.junit.Test)

Example 4 with IndexPacket

use of i2p.bote.packet.dht.IndexPacket in project i2p.i2p-bote by i2p.

the class IndexPacketFolder method deleteExpired.

/**
 * Does not add a Deletion Record, just deletes the file.
 */
@Override
public synchronized void deleteExpired() {
    long currentTime = System.currentTimeMillis();
    for (IndexPacket indexPacket : this) {
        // true if at least one entry was removed
        boolean removed = false;
        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)
                // don't merge, but overwrite the file with the entry/entries removed
                super.store(indexPacket);
        }
    }
}
Also used : IndexPacket(i2p.bote.packet.dht.IndexPacket) IndexPacketEntry(i2p.bote.packet.dht.IndexPacketEntry)

Example 5 with IndexPacket

use of i2p.bote.packet.dht.IndexPacket in project i2p.i2p-bote by i2p.

the class IndexPacketFolder method individualPackets.

/**
 * Overridden to put each index packet entry in its own index packet
 */
@Override
public Iterator<IndexPacket> individualPackets() {
    final Iterator<IndexPacket> bigPackets = super.individualPackets();
    return new Iterator<IndexPacket>() {

        IndexPacket currentPacket;

        Iterator<IndexPacketEntry> currentPacketIterator;

        @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;
        }

        @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;
        }

        @Override
        public void remove() {
            throw new UnsupportedOperationException("Not supported!");
        }
    };
}
Also used : IndexPacket(i2p.bote.packet.dht.IndexPacket) Iterator(java.util.Iterator) IndexPacketEntry(i2p.bote.packet.dht.IndexPacketEntry)

Aggregations

IndexPacket (i2p.bote.packet.dht.IndexPacket)13 DhtStorablePacket (i2p.bote.packet.dht.DhtStorablePacket)6 Test (org.junit.Test)5 EncryptedEmailPacket (i2p.bote.packet.dht.EncryptedEmailPacket)4 IndexPacketDeleteRequest (i2p.bote.packet.dht.IndexPacketDeleteRequest)4 IndexPacketEntry (i2p.bote.packet.dht.IndexPacketEntry)4 Email (i2p.bote.email.Email)2 EmailDestination (i2p.bote.email.EmailDestination)2 EmailIdentity (i2p.bote.email.EmailIdentity)2 DeletionInfoPacket (i2p.bote.packet.dht.DeletionInfoPacket)2 DeletionRecord (i2p.bote.packet.dht.DeletionRecord)2 File (java.io.File)2 ArrayList (java.util.ArrayList)2 InternetAddress (javax.mail.internet.InternetAddress)2 Destination (net.i2p.data.Destination)2 Hash (net.i2p.data.Hash)2 UniqueId (i2p.bote.UniqueId)1 EmailMetadata (i2p.bote.email.EmailMetadata)1 EmailStatus (i2p.bote.folder.Outbox.EmailStatus)1 DhtException (i2p.bote.network.DhtException)1