use of i2p.bote.packet.dht.StoreRequest in project i2p.i2p-bote by i2p.
the class KademliaDHT method store.
@Override
public void store(DhtStorablePacket packet) throws DhtException, InterruptedException {
Hash key = packet.getDhtKey();
log.info("Looking up nodes to store a " + packet.getClass().getSimpleName() + " with key " + key);
List<Destination> closeNodes = getClosestNodes(key);
if (closeNodes.isEmpty())
throw new DhtException("Cannot store packet because no storage nodes found.");
// store on local node if appropriate
if (!closeNodes.contains(localDestination))
if (closeNodes.size() < KademliaConstants.K || isCloser(localDestination, closeNodes.get(0), key))
closeNodes.add(localDestination);
log.info("Storing a " + packet.getClass().getSimpleName() + " with key " + key + " on " + closeNodes.size() + " nodes");
PacketBatch batch = new PacketBatch();
for (Destination node : closeNodes) if (localDestination.equals(node))
storeLocally(packet, null);
else {
// use a separate packet id for each request
StoreRequest storeRequest = new StoreRequest(packet);
batch.putPacket(storeRequest, node);
}
sendQueue.send(batch);
batch.awaitSendCompletion();
// TODO awaitAllResponses, repeat if necessary
sendQueue.remove(batch);
}
use of i2p.bote.packet.dht.StoreRequest 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);
}
use of i2p.bote.packet.dht.StoreRequest in project i2p.i2p-bote by i2p.
the class RelayPacketHandler method packetReceived.
@Override
public void packetReceived(CommunicationPacket packet, Destination sender, long receiveTime) {
if (packet instanceof RelayRequest && dht.isReady()) {
RelayRequest relayRequest = (RelayRequest) packet;
CommunicationPacket payload;
try {
payload = relayRequest.getStoredPacket(i2pSession);
} catch (DataFormatException e) {
log.error("Invalid RelayRequest received from peer " + Util.toBase32(sender), e);
return;
} catch (MalformedPacketException e) {
log.error("Invalid RelayRequest received from peer " + Util.toBase32(sender), e);
return;
}
log.debug("Received a relay request, payload: " + payload);
if (payload instanceof RelayRequest) {
log.debug("Relay packet is of type " + payload.getClass().getSimpleName() + ", storing it in the relay packet folder.");
relayPacketFolder.add((RelayRequest) payload);
confirm(sender, relayRequest);
} else if (payload instanceof StoreRequest) {
log.debug("Relay packet is of type " + payload.getClass().getSimpleName() + ", storing it in the DHT.");
final DhtStorablePacket dhtPacket = ((StoreRequest) payload).getPacketToStore();
// do dht.store() in a separate thread so we don't block the notifier thread
dhtTaskExecutor.submit(new Runnable() {
@Override
public void run() {
try {
dht.store(dhtPacket);
log.debug("Finished storing DHT packet: " + dhtPacket);
} catch (InterruptedException e) {
log.debug("Interrupted while storing packet in the DHT.");
} catch (DhtException e) {
log.error("Error storing packet in the DHT: " + dhtPacket, e);
}
}
});
confirm(sender, relayRequest);
} else
log.error("Don't know how to handle relay packet of type " + payload.getClass());
}
}
use of i2p.bote.packet.dht.StoreRequest 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.StoreRequest in project i2p.i2p-bote by i2p.
the class RelayPacketFolderTest method setUp.
@Before
public void setUp() throws Exception {
File tempDir = new File(System.getProperty("java.io.tmpdir"));
testDir = new File(tempDir, "RelayPacketFolderTest-" + System.currentTimeMillis());
folderDir = new File(testDir, "relay_pkt");
folder = new RelayPacketFolder(folderDir);
// make an EncryptedEmailPacket
String base64Destination = "X3oKYQJ~1EAz7B1ZYGSrOTIMCW5Rnn2Svoc38dx5D9~zvz8vqiWcH-pCqQDwLgPWl9RTBzHtTmZcGRPXIv54i0XWeUfX6rTPDQGuZsnBMM0xrkH2FNLNFaJa0NgW3uKXWpNj9AI1AXUXzK-2MYTYoaZHx5SBoCaKfAGMcFJvTON1~kopxBxdBF9Q7T4~PJ3I2LeU-ycmUlehe9N9bIu7adUGyPGVl8Ka-UxwQromoJ~vSWHHl8HkwcDkW--v9Aj~wvFqxqriFkB1EeBiThi3V4XtVY~GUP4IkRj9YZGTsSBf3eS4xwXgnYWlB7IvxAGBfHY9MCg3lbAa1Dg~1IH6rhtXxsXUtGcXsz9yMZTxXHd~rGo~JrXeM1y~Vcenpr6tJcum6pxevkKzzT0qDegGPH3Zhqz7sSeeIaJEcPBUAkX89csqyFWFIjTMm6yZp2rW-QYUnVNLNTjf7vndYUAEICogAkq~btqpIzrGEpm3Pr9F23br3SpbOmdxQxg51AMmAAAA";
Destination nextDestination = new Destination(base64Destination.substring(0, 516));
long delayMilliseconds = TimeUnit.MILLISECONDS.convert(111, TimeUnit.MINUTES);
String content = "Warum, warum, warum\n" + "Ist die Banane krumm?\n" + "Weil niemand in den Urwald zog\n" + "Und die Banane grade bog.\n";
byte[] messageIdBytes = new byte[] { -69, -24, -109, 1, 69, -122, -69, 113, -68, -90, 55, -28, 105, 97, 125, 70, 51, 58, 14, 2, -13, -53, 90, -29, 36, 67, 36, -94, -108, -125, 11, 123 };
UniqueId messageId = new UniqueId(messageIdBytes, 0);
int fragmentIndex = 0;
InputStream contentStream = new ByteArrayInputStream(content.getBytes());
UnencryptedEmailPacket unencryptedPacket = new UnencryptedEmailPacket(contentStream, messageId, fragmentIndex, I2PBotePacket.MAX_DATAGRAM_SIZE);
unencryptedPacket.setNumFragments(1);
String base64EmailDest = "rIbyUukqtsacD-MDJJ8KbIP9d3WQQo~t~zysc3bNcF1mSwz9PcGJnvWCNhnG2nzbdUAIDouESZjLRnBr7-mxNS";
EmailDestination recipient = new EmailDestination(base64EmailDest);
emailPacket = new EncryptedEmailPacket(unencryptedPacket, recipient);
// make a RelayRequest
StoreRequest storeRequest = new StoreRequest(emailPacket);
relayRequest = new RelayRequest(storeRequest, nextDestination, delayMilliseconds, 1000);
}
Aggregations