Search in sources :

Example 1 with DeleteRequest

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

the class KademliaDHT method storeLocally.

/**
 * Stores a DHT packet locally. The folder the packet is stored in depends on the packet type.
 * @param packetToStore
 * @param sender The peer that sent the store request; can be <code>null</code> for the local node
 */
private void storeLocally(DhtStorablePacket packetToStore, Destination sender) {
    if (packetToStore != null) {
        DhtStorageHandler storageHandler = storageHandlers.get(packetToStore.getClass());
        if (storageHandler != null) {
            // If another peer is trying to store a packet that we know has been deleted, let them know and don't store the packet.
            if (storageHandler instanceof DeletionAwareDhtFolder<?> && sender != null) {
                DeletionAwareDhtFolder<?> folder = (DeletionAwareDhtFolder<?>) storageHandler;
                DeleteRequest delRequest = folder.storeAndCreateDeleteRequest(packetToStore);
                if (delRequest != null)
                    sendQueue.send(delRequest, sender);
            } else
                storageHandler.store(packetToStore);
            replicateThread.packetStored(storageHandler, packetToStore);
        } else
            log.warn("No storage handler found for type " + packetToStore.getClass().getSimpleName() + ".");
    }
}
Also used : DhtStorageHandler(i2p.bote.network.DhtStorageHandler) DeleteRequest(i2p.bote.packet.dht.DeleteRequest) DeletionAwareDhtFolder(i2p.bote.folder.DeletionAwareDhtFolder)

Example 2 with DeleteRequest

use of i2p.bote.packet.dht.DeleteRequest 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);
}
Also used : DhtStorablePacket(i2p.bote.packet.dht.DhtStorablePacket) Destination(net.i2p.data.Destination) DhtStorageHandler(i2p.bote.network.DhtStorageHandler) StoreRequest(i2p.bote.packet.dht.StoreRequest) Iterator(java.util.Iterator) List(java.util.List) Hash(net.i2p.data.Hash) DeleteRequest(i2p.bote.packet.dht.DeleteRequest)

Example 3 with DeleteRequest

use of i2p.bote.packet.dht.DeleteRequest 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 4 with DeleteRequest

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

the class EmailPacketFolder method storeAndCreateDeleteRequest.

@Override
public DeleteRequest storeAndCreateDeleteRequest(DhtStorablePacket packetToStore) {
    if (!(packetToStore instanceof EncryptedEmailPacket))
        throw new IllegalArgumentException("Invalid packet type: " + packetToStore.getClass().getSimpleName() + "; this folder only stores packets of type " + EncryptedEmailPacket.class.getSimpleName() + ".");
    DeleteRequest delRequest = null;
    // read the deletion info file for the email packet's DHT key
    Hash dhtKey = packetToStore.getDhtKey();
    String delFileName = getDeletionFileName(dhtKey);
    DeletionInfoPacket delInfo = createDelInfoPacket(delFileName);
    if (delInfo != null) {
        DeletionRecord delRecord = delInfo.getEntry(dhtKey);
        if (delRecord != null)
            delRequest = new EmailPacketDeleteRequest(delRecord.dhtKey, delRecord.delAuthorization);
    } else
        // if the DHT key has not been recorded as deleted, store the email packet
        store(packetToStore);
    return delRequest;
}
Also used : EmailPacketDeleteRequest(i2p.bote.packet.dht.EmailPacketDeleteRequest) DeletionInfoPacket(i2p.bote.packet.dht.DeletionInfoPacket) DeletionRecord(i2p.bote.packet.dht.DeletionRecord) EncryptedEmailPacket(i2p.bote.packet.dht.EncryptedEmailPacket) Hash(net.i2p.data.Hash) DeleteRequest(i2p.bote.packet.dht.DeleteRequest) EmailPacketDeleteRequest(i2p.bote.packet.dht.EmailPacketDeleteRequest)

Example 5 with DeleteRequest

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

the class KademliaDHT method packetReceived.

// PacketListener implementation
@Override
public void packetReceived(CommunicationPacket packet, Destination sender, long receiveTime) {
    if (packet instanceof FindClosePeersPacket)
        sendPeerList((FindClosePeersPacket) packet, sender);
    else if (packet instanceof StoreRequest) {
        DhtStorablePacket packetToStore = ((StoreRequest) packet).getPacketToStore();
        storeLocally(packetToStore, sender);
    } else if (packet instanceof RetrieveRequest) {
        RetrieveRequest retrieveRequest = (RetrieveRequest) packet;
        DhtStorageHandler storageHandler = storageHandlers.get(retrieveRequest.getDataType());
        if (storageHandler != null) {
            DhtStorablePacket storedPacket = storageHandler.retrieve(retrieveRequest.getKey());
            // if requested packet found, send it to the requester
            Collection<ResponsePacket> response = ResponsePacket.create(storedPacket, StatusCode.OK, retrieveRequest.getPacketId());
            if (storedPacket != null)
                log.debug("Packet found for retrieve request: [" + retrieveRequest + "], replying to sender: [" + Util.toBase32(sender) + "]");
            else
                log.debug("No matching packet found for retrieve request: [" + retrieveRequest + "]");
            sendQueue.send(response, sender);
        } else
            log.warn("No storage handler found for type " + packet.getClass().getSimpleName() + ".");
    } else if (packet instanceof DeleteRequest) {
        DeleteRequest delRequest = (DeleteRequest) packet;
        DhtStorageHandler storageHandler = storageHandlers.get(delRequest.getDataType());
        if (storageHandler instanceof DeletionAwareDhtFolder<?>)
            ((DeletionAwareDhtFolder<?>) storageHandler).process(delRequest);
    } else if (packet instanceof DeletionQuery) {
        DhtStorageHandler storageHandler = storageHandlers.get(EncryptedEmailPacket.class);
        if (storageHandler instanceof DeletionAwareDhtFolder) {
            Hash dhtKey = ((DeletionQuery) packet).getDhtKey();
            UniqueId delAuthorization = ((DeletionAwareDhtFolder<?>) storageHandler).getDeleteAuthorization(dhtKey);
            // If we know the Delete Authorization for the DHT key, send it to the peer
            if (delAuthorization != null) {
                DeletionInfoPacket delInfo = new DeletionInfoPacket();
                delInfo.put(dhtKey, delAuthorization);
                Collection<ResponsePacket> response = ResponsePacket.create(delInfo, StatusCode.OK, packet.getPacketId());
                sendQueue.send(response, sender);
            }
        }
    }
    // bucketManager is not registered as a PacketListener, so notify it here
    bucketManager.packetReceived(packet, sender, receiveTime);
}
Also used : DhtStorablePacket(i2p.bote.packet.dht.DhtStorablePacket) RetrieveRequest(i2p.bote.packet.dht.RetrieveRequest) UniqueId(i2p.bote.UniqueId) StoreRequest(i2p.bote.packet.dht.StoreRequest) Hash(net.i2p.data.Hash) FindClosePeersPacket(i2p.bote.packet.dht.FindClosePeersPacket) DeletionAwareDhtFolder(i2p.bote.folder.DeletionAwareDhtFolder) DeletionQuery(i2p.bote.packet.dht.DeletionQuery) DeletionInfoPacket(i2p.bote.packet.dht.DeletionInfoPacket) ResponsePacket(i2p.bote.packet.ResponsePacket) DhtStorageHandler(i2p.bote.network.DhtStorageHandler) DeleteRequest(i2p.bote.packet.dht.DeleteRequest)

Aggregations

DeleteRequest (i2p.bote.packet.dht.DeleteRequest)7 Hash (net.i2p.data.Hash)5 DeletionInfoPacket (i2p.bote.packet.dht.DeletionInfoPacket)4 DhtStorageHandler (i2p.bote.network.DhtStorageHandler)3 DeletionRecord (i2p.bote.packet.dht.DeletionRecord)3 DhtStorablePacket (i2p.bote.packet.dht.DhtStorablePacket)3 EncryptedEmailPacket (i2p.bote.packet.dht.EncryptedEmailPacket)3 UniqueId (i2p.bote.UniqueId)2 DeletionAwareDhtFolder (i2p.bote.folder.DeletionAwareDhtFolder)2 DataPacket (i2p.bote.packet.DataPacket)2 EmailPacketDeleteRequest (i2p.bote.packet.dht.EmailPacketDeleteRequest)2 StoreRequest (i2p.bote.packet.dht.StoreRequest)2 File (java.io.File)2 Test (org.junit.Test)2 ResponsePacket (i2p.bote.packet.ResponsePacket)1 DeletionQuery (i2p.bote.packet.dht.DeletionQuery)1 FindClosePeersPacket (i2p.bote.packet.dht.FindClosePeersPacket)1 IndexPacket (i2p.bote.packet.dht.IndexPacket)1 IndexPacketDeleteRequest (i2p.bote.packet.dht.IndexPacketDeleteRequest)1 RetrieveRequest (i2p.bote.packet.dht.RetrieveRequest)1