use of i2p.bote.packet.DataPacket in project i2p.i2p-bote by i2p.
the class KademliaDHT method findDeleteAuthorizationKey.
@Override
public UniqueId findDeleteAuthorizationKey(Hash dhtKey, Hash verificationHash) throws InterruptedException {
final Collection<Destination> closeNodes = getClosestNodes(dhtKey);
log.info("Querying " + closeNodes.size() + " peers with DeletionQueries for Kademlia key " + dhtKey);
DhtStorageHandler storageHandler = storageHandlers.get(EncryptedEmailPacket.class);
if (storageHandler instanceof DeletionAwareDhtFolder) {
DeletionAwareDhtFolder<?> folder = (DeletionAwareDhtFolder<?>) storageHandler;
UniqueId delAuthorization = folder.getDeleteAuthorization(dhtKey);
if (delAuthorization != null)
return delAuthorization;
} else
log.error("StorageHandler for EncryptedEmailPackets is not a DeletionAwareDhtFolder!");
// Send the DeletionQueries
PacketBatch batch = new PacketBatch();
for (Destination node : closeNodes) if (// local has already been taken care of
!localDestination.equals(node))
batch.putPacket(new DeletionQuery(dhtKey), node);
sendQueue.send(batch);
batch.awaitSendCompletion();
// wait for replies
batch.awaitFirstReply(RESPONSE_TIMEOUT, TimeUnit.SECONDS);
log.info(batch.getResponses().size() + " response packets received for deletion query for hash " + dhtKey);
sendQueue.remove(batch);
Map<Destination, DataPacket> responses = batch.getResponses();
for (DataPacket response : responses.values()) if (response instanceof DeletionInfoPacket) {
DeletionInfoPacket delInfo = (DeletionInfoPacket) response;
DeletionRecord delRecord = delInfo.getEntry(dhtKey);
if (delRecord != null) {
boolean valid = Util.isDeleteAuthorizationValid(verificationHash, delRecord.delAuthorization);
if (valid)
return delRecord.delAuthorization;
}
}
return null;
}
use of i2p.bote.packet.DataPacket in project i2p.i2p-bote by i2p.
the class KademliaDHT method getDhtResults.
/**
* Returns all <code>DhtStorablePacket</code> packets that have been received as a response to a send batch,
* plus <code>localResult</code> if it is non-<code>null</code>.
* @param batch
* @param localResult
*/
private DhtResults getDhtResults(PacketBatch batch, DhtStorablePacket localResult) {
Map<Destination, DataPacket> responses = batch.getResponses();
DhtResults results = new DhtResults();
for (Entry<Destination, DataPacket> result : responses.entrySet()) {
DataPacket packet = result.getValue();
if (packet instanceof DhtStorablePacket)
results.put(result.getKey(), (DhtStorablePacket) packet);
}
int totalResponses = responses.size();
if (localResult != null) {
results.put(localDestination, localResult);
totalResponses++;
}
results.setTotalResponses(totalResponses);
return results;
}
use of i2p.bote.packet.DataPacket in project i2p.i2p-bote by i2p.
the class RelayPeerManager method run.
@Override
public void run() {
while (!Thread.interrupted()) {
try {
// ask all peers for their peer lists
Set<RelayPeer> peersToQuery = new HashSet<RelayPeer>(peers);
PacketBatch batch = new PacketBatch();
for (RelayPeer peer : peersToQuery) // don't reuse request packets because PacketBatch will not add the same one more than once
batch.putPacket(new PeerListRequest(), peer);
sendQueue.send(batch);
batch.awaitSendCompletion();
batch.awaitAllResponses(2, TimeUnit.MINUTES);
// build a Set of destinations
Set<Destination> responders = batch.getResponses().keySet();
// update reachability data
log.debug("Relay peer stats:");
for (RelayPeer peer : peersToQuery) {
// use peersToQuery (not peers) so new peers that have been added in the meantime are not wrongly considered unresponsive
boolean didRespond = responders.contains(peer);
peer.addReachabilitySample(didRespond);
if (log.shouldLog(Log.DEBUG)) {
StringBuilder logMessage = new StringBuilder(" ");
logMessage.append(Util.toBase32(peer));
logMessage.append(" ");
for (boolean responded : peer.getAllSamples()) logMessage.append(responded ? '*' : '.');
log.debug(logMessage.toString());
}
}
// make a Set with the new peers
Set<Destination> receivedPeers = new HashSet<Destination>();
BanList banList = BanList.getInstance();
for (DataPacket response : batch.getResponses().values()) {
if (!(response instanceof PeerList))
continue;
PeerList peerList = (PeerList) response;
for (Destination peer : peerList.getPeers()) if (!banList.isBanned(peer))
receivedPeers.add(peer);
}
log.debug("Received a total of " + receivedPeers.size() + " relay peers in " + batch.getResponses().size() + " packets.");
// replace low-reachability peers with new peers (a PeerList is supposed to contain only high-reachability peers)
synchronized (peers) {
// add all received peers, then remove low-reachability ones (all of which are existing peers)
for (Destination newPeer : receivedPeers) if (!localDestination.equals(newPeer))
peers.add(new RelayPeer(newPeer));
for (Iterator<RelayPeer> iterator = peers.iterator(); iterator.hasNext(); ) {
if (peers.size() <= MAX_PEERS)
break;
RelayPeer peer = iterator.next();
if (// don't remove the peer before it has had a chance to respond to a request
!peer.getAllSamples().isEmpty() && peer.getReachability() < MIN_REACHABILITY)
iterator.remove();
}
}
log.debug("Number of relay peers is now " + peers.size());
// if no good peers available, ask more often
if (getGoodPeers().isEmpty())
TimeUnit.MINUTES.sleep(UPDATE_INTERVAL_SHORT);
else
TimeUnit.MINUTES.sleep(UPDATE_INTERVAL_LONG);
} catch (InterruptedException e) {
break;
} catch (RuntimeException e) {
// catch unexpected exceptions to keep the thread running
log.error("Exception caught in RelayPeerManager loop", e);
}
}
writePeers(peerFile);
log.debug("RelayPeerManager thread exiting.");
}
use of i2p.bote.packet.DataPacket in project i2p.i2p-bote by i2p.
the class I2PSendQueue method packetReceived.
// Implementation of PacketListener
@Override
public void packetReceived(CommunicationPacket packet, Destination sender, long receiveTime) {
if (packet instanceof ResponsePacket) {
UniqueId packetId = packet.getPacketId();
for (PacketBatch batch : runningBatches) if (batch.contains(packetId)) {
DataPacket payload = ((ResponsePacket) packet).getPayload();
if (payload != null)
batch.addResponse(sender, payload);
else
batch.addResponse(sender, new EmptyResponse());
}
}
}
use of i2p.bote.packet.DataPacket 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());
}
Aggregations