use of i2p.bote.packet.dht.DhtStorablePacket 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.DhtStorablePacket in project i2p.i2p-bote by i2p.
the class EmailPacketFolder method process.
/**
* Deletes email packets.
* @param delRequest An instance of {@link EmailPacketDeleteRequest}
*/
@Override
public synchronized void process(DeleteRequest delRequest) {
log.debug("Processing delete request: " + delRequest);
if (!(delRequest instanceof EmailPacketDeleteRequest))
log.error("Invalid type of delete request for EmailPacketFolder: " + delRequest.getClass());
EmailPacketDeleteRequest emailPacketDelRequest = (EmailPacketDeleteRequest) delRequest;
// see if the packet exists
Hash dhtKey = emailPacketDelRequest.getDhtKey();
DhtStorablePacket storedPacket = retrieve(dhtKey);
if (storedPacket instanceof EncryptedEmailPacket) {
// verify
Hash verificationHash = ((EncryptedEmailPacket) storedPacket).getDeleteVerificationHash();
UniqueId delAuthorization = emailPacketDelRequest.getAuthorization();
boolean valid = Util.isDeleteAuthorizationValid(verificationHash, delAuthorization);
if (valid)
delete(dhtKey, delAuthorization);
else
log.debug("Invalid Delete Authorization in EmailPacketDeleteRequest. Should be: <" + verificationHash.toBase64() + ">");
} else if (storedPacket != null)
log.debug("EncryptedEmailPacket expected for DHT key <" + dhtKey + ">, found " + storedPacket.getClass().getSimpleName());
}
use of i2p.bote.packet.dht.DhtStorablePacket in project i2p.i2p-bote by i2p.
the class CheckEmailTask method getIndexPackets.
/**
* Returns all Index Packets in a <code>Collection</code> of {@link DhtStorablePacket}s.
* @param dhtPackets Should only contain index packets; other packets are ignored
* @return An <code>IndexPacket</code> containing all entries from the packets in the <code>Collection</code>
*/
private Collection<IndexPacket> getIndexPackets(Collection<DhtStorablePacket> dhtPackets) {
Collection<IndexPacket> indexPackets = new ArrayList<IndexPacket>();
for (DhtStorablePacket packet : dhtPackets) if (packet instanceof IndexPacket)
indexPackets.add((IndexPacket) packet);
else
log.error("DHT returned packet of class " + packet.getClass().getSimpleName() + ", expected IndexPacket.");
return indexPackets;
}
use of i2p.bote.packet.dht.DhtStorablePacket 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);
}
use of i2p.bote.packet.dht.DhtStorablePacket in project i2p.i2p-bote by i2p.
the class KademliaDHT method find.
private DhtResults find(Hash key, Class<? extends DhtStorablePacket> dataType, boolean exhaustive) throws InterruptedException {
final Collection<Destination> closeNodes = getClosestNodes(key);
log.info("Querying localhost + " + closeNodes.size() + " peers for data type " + dataType.getSimpleName() + ", Kademlia key " + key);
DhtStorablePacket localResult = findLocally(key, dataType);
// if a local packet exists and one result is requested, return the local packet
if (!exhaustive && localResult != null) {
log.debug("Locally stored packet found for hash " + key + " and data type " + dataType.getSimpleName());
DhtResults results = new DhtResults();
results.put(localDestination, localResult);
return results;
}
// Send the retrieve requests
PacketBatch batch = new PacketBatch();
for (Destination node : closeNodes) if (// local has already been taken care of
!localDestination.equals(node))
batch.putPacket(new RetrieveRequest(key, dataType), node);
sendQueue.send(batch);
batch.awaitSendCompletion();
// wait for replies
if (exhaustive)
batch.awaitAllResponses(RESPONSE_TIMEOUT, TimeUnit.SECONDS);
else
batch.awaitFirstReply(RESPONSE_TIMEOUT, TimeUnit.SECONDS);
log.info(batch.getResponses().size() + " response packets received for hash " + key + " and data type " + dataType.getSimpleName());
sendQueue.remove(batch);
return getDhtResults(batch, localResult);
}
Aggregations