public StoreRequest(byte[] data) throws NoSuchAlgorithmException, MalformedPacketException { super(data); ByteBuffer buffer = ByteBuffer.wrap(data, HEADER_LENGTH, data.length-HEADER_LENGTH); int hashCashLength = buffer.getShort() & 0xFFFF; byte[] hashCashData = new byte[hashCashLength]; buffer.get(hashCashData); hashCash = new HashCash(new String(hashCashData)); int dataLength = buffer.getShort() & 0xFFFF; byte[] storedData = new byte[dataLength]; buffer.get(storedData); packetToStore = DhtStorablePacket.createPacket(storedData); if (buffer.hasRemaining()) log.debug("Storage Request Packet has " + buffer.remaining() + " extra bytes."); }
public RetrieveRequest(byte[] data) { super(data); ByteBuffer buffer = ByteBuffer.wrap(data, HEADER_LENGTH, data.length-HEADER_LENGTH); char dataTypeCode = (char)buffer.get(); dataType = DhtStorablePacket.decodePacketTypeCode(dataTypeCode); byte[] keyBytes = new byte[Hash.HASH_LENGTH]; buffer.get(keyBytes); key = new Hash(keyBytes); if (buffer.hasRemaining()) log.debug("Retrieve Request Packet has " + buffer.remaining() + " extra bytes."); }
public Hash getKey() { return packetToStore.getDhtKey(); }
@Override public byte[] toByteArray() { ByteArrayOutputStream byteArrayStream = new ByteArrayOutputStream(); DataOutputStream dataStream = new DataOutputStream(byteArrayStream); try { writeHeader(dataStream); String hashCashString = hashCash.toString(); dataStream.writeShort(hashCashString.length()); dataStream.write(hashCashString.getBytes()); byte[] dataToStore = packetToStore.toByteArray(); dataStream.writeShort(dataToStore.length); dataStream.write(dataToStore); } catch (IOException e) { log.error("Can't write to ByteArrayOutputStream.", e); } return byteArrayStream.toByteArray(); }
@Override public String toString() { return super.toString() + ", DHTkey=" + dhtKey + ", tstamp=" + storeTime + ", alg=" + cryptoImpl.getName() + ", delVerifHash=" + delVerificationHash + ", encrLen=" + encryptedData.length; } }
@Test public void testGetPacketToStore() throws Exception { byte[] arrayA = dhtPacket.toByteArray(); byte[] arrayB = storeRequest.getPacketToStore().toByteArray(); assertArrayEquals("The two arrays differ!", arrayA, arrayB); } }
/** * Informs the <code>ReplicationThread</code> that a packet has been stored in a local folder. * @param folder * @param packet */ public void packetStored(DhtStorageHandler folder, DhtStorablePacket packet) { keysToSkip.add(packet.getDhtKey()); }
@Override public DhtStorablePacket retrieve(Hash dhtKey) { File packetFile = findPacketFile(dhtKey); if (packetFile != null) try { return DhtStorablePacket.createPacket(packetFile); } catch (MalformedPacketException e) { log.error("Cannot create packet from file: <" + packetFile.getAbsolutePath() + ">", e); return null; } else return null; }
@Override public void store(DhtStorablePacket packetToStore) { add(packetToStore, getFilename(packetToStore.getDhtKey())); }
@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; } }
@Override public void store(DhtStorablePacket packetToStore) { File packetFile = findPacketFile(packetToStore.getDhtKey()); if (packetFile != null) log.debug("Not storing directory packet with DHT key " + packetToStore.getDhtKey() + " because file exists."); else { if (!(packetToStore instanceof Contact)) log.error("Expected class Contact, got " + packetToStore.getClass()); else { Contact contact = (Contact)packetToStore; try { if (!contact.verify()) log.debug("Not storing Contact because verification failed."); else super.store(packetToStore); } catch (GeneralSecurityException e) { log.error("Can't verify Contact", e); } } } } }
@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 { StoreRequest storeRequest = new StoreRequest(packet); // use a separate packet id for each request batch.putPacket(storeRequest, node); } sendQueue.send(batch); batch.awaitSendCompletion(); // TODO awaitAllResponses, repeat if necessary sendQueue.remove(batch); }
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);
DhtStorablePacket existingPacket = super.retrieve(packetToStore.getDhtKey()); // use super.retrieve() because we don't want to delete time stamps here String delFileName = getDeletionFileName(packetToStore.getDhtKey()); DeletionInfoPacket delInfo = createDelInfoPacket(delFileName); IndexPacketDeleteRequest delRequest = null;