public CHKBlock fetch(NodeCHK chk, boolean dontPromote, boolean ignoreOldBlocks, BlockMetadata meta) throws IOException { // FIXME optimize: change API so we can just pass in the crypto algorithm rather than having to construct the full key??? return store.fetch(chk.getRoutingKey(), chk.getFullKey(), dontPromote, false, false, ignoreOldBlocks, meta); }
@Override public Key archivalCopy() { return new NodeCHK(this); } }
@Override public boolean equals(Object o) { if(!(o instanceof CHKBlock)) return false; CHKBlock block = (CHKBlock) o; if(!chk.equals(block.chk)) return false; if(!Arrays.equals(data, block.data)) return false; if(!Arrays.equals(headers, block.headers)) return false; if(hashIdentifier != block.hashIdentifier) return false; return true; }
@Override public byte[] getFullKey() { return getKey().getFullKey(); }
hashCode = key.hashCode() ^ Fields.hashCode(data) ^ Fields.hashCode(headers) ^ cryptoAlgorithm; return; SHA256.returnMessageDigest(md); if(key == null) { chk = new NodeCHK(hash, cryptoAlgorithm); } else { chk = key; hashCode = chk.hashCode() ^ Fields.hashCode(data) ^ Fields.hashCode(headers) ^ cryptoAlgorithm;
private boolean keysValid(ClientCHK[] keys) { for(ClientCHK key: keys) if(key.getNodeCHK().getRoutingKey() == null) return false; return true; }
@Override public byte[] getFullKey() { byte[] buf = new byte[FULL_KEY_LENGTH]; short type = getType(); buf[0] = (byte) (type >> 8); buf[1] = (byte) (type & 0xFF); System.arraycopy(routingKey, 0, buf, 2, routingKey.length); return buf; }
@Override public byte[] routingKeyFromFullKey(byte[] keyBuf) { return NodeCHK.routingKeyFromFullKey(keyBuf); }
/** * Read a Key from a RandomAccessFile * @param raf The file to read from. * @return a Key, or throw an exception, or return null if the key is not parsable. */ public static Key read(DataInput raf) throws IOException { byte type = raf.readByte(); byte subtype = raf.readByte(); if(type == NodeCHK.BASE_TYPE) { return NodeCHK.readCHK(raf, subtype); } else if(type == NodeSSK.BASE_TYPE) return NodeSSK.readSSK(raf, subtype); throw new IOException("Unrecognized format: "+type); }
@Override public CHKBlock construct(byte[] data, byte[] headers, byte[] routingKey, byte[] fullKey, boolean canReadClientCache, boolean canReadSlashdotCache, BlockMetadata meta, DSAPublicKey ignored) throws KeyVerifyException { if(data == null || headers == null) throw new CHKVerifyException("Need either data and headers"); return CHKBlock.construct(data, headers, NodeCHK.cryptoAlgorithmFromFullKey(fullKey)); }
@Override public Key getNodeKey(boolean cloneKey) { return cloneKey ? getNodeCHK().cloneKey() : getNodeCHK(); }
ClientCHK key = block.getClientKey(); assertNotNull(saltStore.fetch(key.getRoutingKey(), key.getNodeCHK().getFullKey(), false, false, false, false, null)); CHKBlock verify = store.fetch(key.getNodeCHK(), false, false, null); String receivedData = decodeBlockCHK(verify, key);
@Override public byte[] getRoutingKey() { return getKey().getRoutingKey(); }
@Override public final void write(DataOutput _index) throws IOException { _index.writeShort(getType()); _index.write(routingKey); }
public void testZeroSize() throws IOException, CHKEncodeException, CHKVerifyException, CHKDecodeException { File f = new File(tempDir, "saltstore"); FileUtil.removeAll(f); CHKStore store = new CHKStore(); SaltedHashFreenetStore<CHKBlock> saltStore = SaltedHashFreenetStore.construct(f, "testCachingFreenetStoreCHK", store, weakPRNG, 10, false, SemiOrderedShutdownHook.get(), true, true, ticker, null); CachingFreenetStoreTracker tracker = new CachingFreenetStoreTracker(0, cachingFreenetStorePeriod, ticker); CachingFreenetStore<CHKBlock> cachingStore = new CachingFreenetStore<CHKBlock>(store, saltStore, tracker); cachingStore.start(null, true); for(int i=0;i<5;i++) { String test = "test" + i; ClientCHKBlock block = encodeBlockCHK(test); store.put(block.getBlock(), false); ClientCHK key = block.getClientKey(); // It should pass straight through. assertNotNull(saltStore.fetch(key.getRoutingKey(), key.getNodeCHK().getFullKey(), false, false, false, false, null)); CHKBlock verify = store.fetch(key.getNodeCHK(), false, false, null); String data = decodeBlockCHK(verify, key); assertEquals(test, data); } cachingStore.close(); }
public synchronized NodeCHK getNodeCHK() { // This costs us more or less nothing: we have to keep the routingKey anyway. // Therefore, keeping a NodeCHK as well is a net saving, since it's frequently // asked for. (A SoftReference would cost more). if(nodeKey == null) nodeKey = new NodeCHK(routingKey, cryptoAlgorithm); return nodeKey; }
public int getBlockNumber(NodeCHK key, boolean[] ignoreSlots) { byte[] rkey = key.getRoutingKey(); int x = 0; for(int i=0;i<(dataBlocks + checkBlocks);i++) { int oldX = x; x += NodeCHK.KEY_LENGTH; if(ignoreSlots != null && ignoreSlots[i]) { continue; } if(!Fields.byteArrayEqual(routingKeys, rkey, oldX, 0, NodeCHK.KEY_LENGTH)) continue; return i; } return -1; }
public void senderTransferEnds(NodeCHK key, RequestSender requestSender) { synchronized(this) { if(!senderTransferring) // Already unlocked. This is okay. return; senderTransferring = false; assert(this.sender != null && this.sender.get() == requestSender); assert(this.key != null && this.key.equals(key)); this.key = null; } tracker.removeTransferringSender(key, requestSender); }
public void testSimpleCHK() throws IOException, CHKEncodeException, CHKVerifyException, CHKDecodeException { File f = new File(tempDir, "saltstore"); FileUtil.removeAll(f); CHKStore store = new CHKStore(); SaltedHashFreenetStore<CHKBlock> saltStore = SaltedHashFreenetStore.construct(f, "testCachingFreenetStoreCHK", store, weakPRNG, 10, false, SemiOrderedShutdownHook.get(), true, true, ticker, null); CachingFreenetStoreTracker tracker = new CachingFreenetStoreTracker(cachingFreenetStoreMaxSize, cachingFreenetStorePeriod, ticker); CachingFreenetStore<CHKBlock> cachingStore = new CachingFreenetStore<CHKBlock>(store, saltStore, tracker); cachingStore.start(null, true); for(int i=0;i<5;i++) { String test = "test" + i; ClientCHKBlock block = encodeBlockCHK(test); store.put(block.getBlock(), false); ClientCHK key = block.getClientKey(); // Check that it's in the cache, *not* the underlying store. assertEquals(saltStore.fetch(key.getRoutingKey(), key.getNodeCHK().getFullKey(), false, false, false, false, null), null); CHKBlock verify = store.fetch(key.getNodeCHK(), false, false, null); String data = decodeBlockCHK(verify, key); assertEquals(test, data); } cachingStore.close(); }
@Override public Key cloneKey() { return new NodeCHK(this); }