public Enum<?> putConfirm(PublicKey publicKey, Number640 key, Data newData) { RangeLock<Number640>.Range lock = lock(key); try { if (!securityEntryCheck( key.locationAndDomainAndContentKey(), publicKey, newData.publicKey(), newData.isProtectedEntry())) { return PutStatus.FAILED_SECURITY; } final Data data = backend.get(key); if (data != null) { // remove prepare flag data.prepareFlag(false); data.validFromMillis(newData.validFromMillis()); data.ttlSeconds(newData.ttlSeconds()); long expiration = data.expirationMillis(); // handle timeout backend.addTimeout(key, expiration); backend.put(key, data); // don't release data as we just update return PutStatus.OK; } else { return PutStatus.NOT_FOUND; } } finally { newData.release(); lock.unlock(); } // TODO: check for FORKS! }
public static void main(String[] args) throws Exception { Peer master = null; try { Peer[] peers = ExampleUtils.createAndAttachNodes(100, 4001); master = peers[0]; MyPeer myPeer = new MyPeer(master); ExampleUtils.bootstrap(peers); myPeer .put( "This is my location key", "This is my domain", "This is my content key", "And here comes the data") .awaitUninterruptibly(); FutureDHT futureDHT = myPeer.get("This is my location key", "This is my domain", "This is my content key"); futureDHT.awaitUninterruptibly(); System.err.println(futureDHT.getFailedReason()); Map<Number160, Data> map = futureDHT.getDataMap(); for (Data data : map.values()) { MyData myData = (MyData) data.getObject(); System.out.println( "key: " + myData.getKey() + ", domain: " + myData.getDomain() + ", content: " + myData.getContent() + ", data: " + myData.getData()); } } finally { master.halt(); } }
public NavigableMap<Number640, Data> removeReturnData( Number640 from, Number640 to, PublicKey publicKey) { RangeLock<Number640>.Range lock = rangeLock.lock(from, to); try { Map<Number640, Data> tmp = backend.subMap(from, to); NavigableMap<Number640, Data> result = new TreeMap<Number640, Data>(); for (Number640 key : tmp.keySet()) { // fail fast, as soon as we want to remove 1 domain that we // cannot, abort if (!canClaimDomain(key.locationAndDomainKey(), publicKey)) { result.put(key, null); } else if (!canClaimEntry(key.locationAndDomainAndContentKey(), publicKey)) { result.put(key, null); } else { Data toRemove = backend.get(key); if (toRemove != null && (toRemove.publicKey() == null || toRemove.publicKey().equals(publicKey))) { backend.removeTimeout(key); Data removed = backend.remove(key, true); result.put(key, removed); } } } return result; } finally { lock.unlock(); } }
public void checkTimeout() { long time = System.currentTimeMillis(); Collection<Number640> toRemove = backend.subMapTimeout(time); for (Number640 key : toRemove) { RangeLock<Number640>.Range lock = lock(key); try { Data oldData = backend.remove(key, false); if (oldData != null) { oldData.release(); } backend.removeTimeout(key); // remove responsibility if we don't have any data stored under // locationkey Number160 locationKey = key.locationKey(); RangeLock<Number640>.Range lockResp = lockResponsibility(locationKey); try { if (isEmpty(locationKey)) { backend.removeResponsibility(locationKey); } } finally { lockResp.unlock(); } } finally { lock.unlock(); } } }
public static Data createData( final byte[] me, final int offset, final int length, final int ttl, boolean protectedEntry, PeerAddress originator) { Data data; // length may be 0 if data is only used for expiration if (length == 0) data = new Data(EMPTY_BYTE_ARRAY, originator); else { // check if its worth coping the buffer, or just take the one backed // by the bytebuffer. If the backing buffer is too big, then its a // waste of space and we should copy, otherwise, take the backing // array. // TODO: find good values for this. This is just a guess final boolean copy = true; // final boolean copy = me.length / length > 1; // we have to use copy if we use an exectution handler, otherwise // the buffer will have different data. if (copy) { final byte[] me2 = new byte[length]; System.arraycopy(me, offset, me2, 0, length); data = new Data(me2, 0, length, originator); } else data = new Data(me, offset, length, originator); } data.setTTLSeconds(ttl); data.setProtectedEntry(protectedEntry); return data; }
private void get(Number160 key) { Data data = get(new Number640(key, Number160.ZERO, Number160.ZERO, Number160.ZERO)); byte[] byteArray = new byte[0]; if (data != null) { byteArray = (byte[]) data.toBytes(); } LOG.debug("Got {} bytes", byteArray.length); }
private Data getInternal(Number640 key) { Data data = backend.get(key); if (data != null && !data.hasPrepareFlag()) { return data; } else { return null; } }
public static void inheritPublicKey(Message message, Data data) { if (message.isSign() && message.publicKey(0) != null && data.hasPublicKey() && (data.publicKey() == null || data.publicKey() == PeerBuilder.EMPTY_PUBLIC_KEY)) { data.publicKey(message.publicKey(0)); } }
public Data get(Number640 key) { RangeLock<Number640>.Range lock = lock(key); try { Data tmp = getInternal(key); return tmp == null ? null : tmp.duplicate(); } finally { lock.unlock(); } }
private void add(Peer peer, byte[] key, byte[] value) throws InterruptedException { RoutingConfiguration rc = new RoutingConfiguration(1, 0, 10, 1); RequestP2PConfiguration pc = new RequestP2PConfiguration(3, 5, 0); ConfigurationStore cs = Configurations.defaultStoreConfiguration(); cs.setRequestP2PConfiguration(pc); cs.setRoutingConfiguration(rc); Data data = new Data(value); data.setTTLSeconds(3); peer.add(new Number160(key), data, cs) .addListener( new BaseFutureAdapter<FutureDHT>() { @Override public void operationComplete(final FutureDHT future) throws Exception { System.out.println(future.getRawKeys()); } }); }
/* (non-Javadoc) * @see net.tomp2p.dht.DigestStorage#digest(java.util.Collection) */ @Override public DigestInfo digest(Collection<Number640> number640s) { DigestInfo digestInfo = new DigestInfo(); for (Number640 number640 : number640s) { RangeLock<Number640>.Range lock = lock(number640); try { if (backend.contains(number640)) { Data data = getInternal(number640); if (data != null) { digestInfo.put(number640, data.basedOnSet()); } } } finally { lock.unlock(); } } return digestInfo; }
// iterative version private NavigableMap<Number640, Data> deletePredecessors( Number640 key, NavigableMap<Number640, Data> sortedMap) { final List<Number640> toRemove = new ArrayList<Number640>(); final NavigableMap<Number640, Data> removed = new TreeMap<Number640, Data>(); toRemove.add(key); while (!toRemove.isEmpty()) { final Number640 key2 = toRemove.remove(0); final Data version = sortedMap.remove(key2); if (version != null) { removed.put(key2, version); // check if version has been already deleted && // check if version is initial version if (!version.basedOnSet().isEmpty()) { for (final Number160 basedOnKey : version.basedOnSet()) { toRemove.add(new Number640(key.locationAndDomainAndContentKey(), basedOnKey)); } } } } return removed; }
public void release() { if (message != null) { message.release(); } // release partial data if (data != null) { data.release(); } if (dataMap != null) { for (Data data : dataMap.dataMap().values()) { data.release(); } } if (buffer != null) { buffer.release(); } if (currentTrackerData != null) { currentTrackerData.release(); } if (trackerData != null) { for (Data data : trackerData.peerAddresses().values()) { data.release(); } } }
public boolean put(Number640 key) { Data data = generateRandomData(); long startTime = System.currentTimeMillis(); FuturePut futurePut = peerDHT .put(key.locationKey()) .domainKey(key.domainKey()) .versionKey(key.versionKey()) .data(key.contentKey(), data) .routingConfiguration(routingConfig) .requestP2PConfiguration(requestConfig) .start() .awaitUninterruptibly(); putStats.report(System.currentTimeMillis() - startTime, futurePut.isSuccess()); LOG.debug( "Put of {} bytes is success = {}. Reason: {}", data.length(), futurePut.isSuccess(), futurePut.failedReason()); return futurePut.isSuccess(); }
public Pair<Data, Enum<?>> remove(Number640 key, PublicKey publicKey, boolean returnData) { RangeLock<Number640>.Range lock = lock(key); try { if (!canClaimDomain(key.locationAndDomainKey(), publicKey)) { return new Pair<Data, Enum<?>>(null, PutStatus.FAILED_SECURITY); } if (!canClaimEntry(key.locationAndDomainAndContentKey(), publicKey)) { return new Pair<Data, Enum<?>>(null, PutStatus.FAILED_SECURITY); } if (!backend.contains(key)) { return new Pair<Data, Enum<?>>(null, PutStatus.NOT_FOUND); } backend.removeTimeout(key); Data removed = backend.remove(key, returnData); if (removed != null && !returnData) { removed.release(); } // else -> it will be removed in the encoder return new Pair<Data, Enum<?>>(removed, PutStatus.OK); } finally { lock.unlock(); } }
public static int encodeData(ProtocolChunkedInput input, final Message message, Data data) { int count = 4 + 4; // encode entry protection in millis as the sign bit. Thus the max value // of millis is 2^31, which is more than enough int seconds = data.getTTLSeconds(); seconds = data.isProtectedEntry() ? seconds | 0x80000000 : seconds & 0x7FFFFFFF; input.copyToCurrent(seconds); input.copyToCurrent(data.getLength()); // the real data input.copyToCurrent(data.getData(), data.getOffset(), data.getLength()); count += data.getLength(); return count; }
public Map<Number640, Enum<?>> putAll( final NavigableMap<Number640, Data> dataMap, PublicKey publicKey, boolean putIfAbsent, boolean domainProtection, boolean sendSelf) { if (dataMap.isEmpty()) { return Collections.emptyMap(); } final Number640 min = dataMap.firstKey(); final Number640 max = dataMap.lastKey(); final Map<Number640, Enum<?>> retVal = new HashMap<Number640, Enum<?>>(); final HashSet<Number480> keysToCheck = new HashSet<Number480>(); final RangeLock<Number640>.Range lock = lock(min, max); try { for (Map.Entry<Number640, Data> entry : dataMap.entrySet()) { Number640 key = entry.getKey(); keysToCheck.add(key.locationAndDomainAndContentKey()); Data newData = entry.getValue(); if (!securityDomainCheck( key.locationAndDomainKey(), publicKey, publicKey, domainProtection)) { retVal.put(key, PutStatus.FAILED_SECURITY); newData.release(); continue; } // We need this check in case we did not use the encoder/decoder, // which is the case if we send the message to ourself. In that // case, the public key of the data is never set to the message // publick key, if the publick key of the data was null. final PublicKey dataKey; if (sendSelf && newData.publicKey() == null) { dataKey = publicKey; } else { dataKey = newData.publicKey(); } if (!securityEntryCheck( key.locationAndDomainAndContentKey(), publicKey, dataKey, newData.isProtectedEntry())) { retVal.put(key, PutStatus.FAILED_SECURITY); newData.release(); continue; } final Data oldDataGet = backend.get(key); if (oldDataGet != null) { if (putIfAbsent) { retVal.put(key, PutStatus.FAILED_NOT_ABSENT); newData.release(); continue; } if (oldDataGet.isDeleted()) { retVal.put(key, PutStatus.DELETED); newData.release(); continue; } if (!oldDataGet.basedOnSet().equals(newData.basedOnSet())) { retVal.put(key, PutStatus.VERSION_FORK); newData.release(); continue; } } final Data oldDataPut = backend.put(key, newData); long expiration = newData.expirationMillis(); // handle timeout backend.addTimeout(key, expiration); if (newData.hasPrepareFlag()) { retVal.put(key, PutStatus.OK_PREPARED); } else { retVal.put(key, PutStatus.OK); } if (oldDataPut != null && oldDataPut != newData) { oldDataPut.release(); } } for (Number480 key : keysToCheck) { // now check for forks Number640 minVersion = new Number640(key, Number160.ZERO); Number640 maxVersion = new Number640(key, Number160.MAX_VALUE); NavigableMap<Number640, Data> tmp = backend.subMap(minVersion, maxVersion); tmp = filterCopyOrig(tmp, -1, true); NavigableMap<Number640, Data> heads = getLatestInternalOrig(tmp); final boolean forked = heads.size() > 1; for (final Map.Entry<Number640, Data> entry : heads.entrySet()) { if (forked) { if (retVal.containsKey(entry.getKey())) { retVal.put(entry.getKey(), PutStatus.VERSION_FORK); } } } // now remove old versions if (maxVersions > 0) { NavigableMap<Number640, Data> versions = backend.subMap(minVersion, maxVersion); while (!versions.isEmpty() && versions.firstKey().versionKey().timestamp() + maxVersions <= versions.lastKey().versionKey().timestamp()) { Map.Entry<Number640, Data> entry = versions.pollFirstEntry(); Data removed = backend.remove(entry.getKey(), true); if (removed != null) { removed.release(); } backend.removeTimeout(entry.getKey()); } } } return retVal; } finally { lock.unlock(); } }
/** * Decodes the payload from a Netty buffer in a big switch * * @param content The content type * @param buffer The buffer to read from * @param message The message to store the results * @throws IndexOutOfBoundsException If a buffer is read beyond its limits * @throws NoSuchAlgorithmException * @throws SignatureException * @throws InvalidKeyException * @throws InvalidKeySpecException * @throws InvalidKeySpecException * @throws IOException * @throws DecoderException * @throws ASN1Exception * @throws UnsupportedEncodingException If UTF-8 is not there */ public static boolean decodePayload( final Content content, final ChannelBuffer buffer, final Message message) throws InvalidKeyException, SignatureException, NoSuchAlgorithmException, InvalidKeySpecException, IOException, DecoderException { final int len; byte[] me; switch (content) { case KEY: if (buffer.readableBytes() < 20) return false; message.setKey0(readID(buffer)); return true; case KEY_KEY: if (buffer.readableBytes() < 40) return false; message.setKeyKey0(readID(buffer), readID(buffer)); return true; case MAP_KEY_DATA: if (buffer.readableBytes() < 4) return false; int size = buffer.readInt(); Map<Number160, Data> result = new HashMap<Number160, Data>(size); for (int i = 0; i < size; i++) { if (buffer.readableBytes() < 20) return false; Number160 key = readID(buffer); final Data data = decodeData(new ChannelDecoder(buffer), message.getSender()); if (data == null) return false; if (message.isRequest()) { if (data.isProtectedEntry() && message.getPublicKey() == null) throw new DecoderException( "You indicated that you want to protect the data, but you did not provide or provided too late a public key."); data.setPublicKey(message.getPublicKey()); } result.put(key, data); } message.setDataMap0(result); return true; case MAP_KEY_KEY: if (buffer.readableBytes() < 4) return false; len = buffer.readInt(); if (buffer.readableBytes() < ((20 + 20) * len)) return false; final Map<Number160, Number160> keyMap = new HashMap<Number160, Number160>(); for (int i = 0; i < len; i++) { final Number160 key1 = readID(buffer); final Number160 key2 = readID(buffer); keyMap.put(key1, key2); } message.setKeyMap0(keyMap); return true; case SET_KEYS: // can be 31bit long ~ 2GB if (buffer.readableBytes() < 4) return false; len = buffer.readInt(); if (buffer.readableBytes() < (20 * len)) return false; final Collection<Number160> tmp = new ArrayList<Number160>(len); for (int i = 0; i < len; i++) { Number160 key = readID(buffer); tmp.add(key); } message.setKeys0(tmp); return true; case SET_NEIGHBORS: if (buffer.readableBytes() < 1) return false; len = buffer.readUnsignedByte(); if (buffer.readableBytes() < (len * PeerAddress.SIZE_IPv4)) return false; final Collection<PeerAddress> neighbors = new ArrayList<PeerAddress>(len); for (int i = 0; i < len; i++) { PeerAddress peerAddress = readPeerAddress(buffer); if (peerAddress == null) return false; neighbors.add(peerAddress); } message.setNeighbors0(neighbors); return true; case SET_TRACKER_DATA: if (buffer.readableBytes() < 1) return false; len = buffer.readUnsignedByte(); if (buffer.readableBytes() < (len * (PeerAddress.SIZE_IPv4 + 1))) return false; final Collection<TrackerData> trackerDatas = new ArrayList<TrackerData>(len); for (int i = 0; i < len; i++) { PeerAddress peerAddress = readPeerAddress(buffer); if (peerAddress == null) return false; byte[] attachment = null; int offset = 0; int length = 0; if (buffer.readableBytes() < 1) return false; byte miniHeader = buffer.readByte(); if (miniHeader != 0) { if (buffer.readableBytes() < 4) return false; length = buffer.readInt(); if (buffer.readableBytes() < length) return false; attachment = new byte[length]; buffer.readBytes(attachment); } trackerDatas.add( new TrackerData(peerAddress, message.getSender(), attachment, offset, length)); } message.setTrackerData0(trackerDatas); return true; case CHANNEL_BUFFER: if (buffer.readableBytes() < 4) return false; len = buffer.readInt(); if (buffer.readableBytes() < len) return false; // you can only use slice if no execution handler is in place, // otherwise, you will overwrite stuff final ChannelBuffer tmpBuffer = buffer.slice(buffer.readerIndex(), len); buffer.skipBytes(len); message.setPayload0(tmpBuffer); return true; case LONG: if (buffer.readableBytes() < 8) return false; message.setLong0(buffer.readLong()); return true; case INTEGER: if (buffer.readableBytes() < 4) return false; message.setInteger0(buffer.readInt()); return true; case PUBLIC_KEY: case PUBLIC_KEY_SIGNATURE: if (buffer.readableBytes() < 2) return false; len = buffer.readUnsignedShort(); me = new byte[len]; if (buffer.readableBytes() < len) return false; message.setPublicKey0(decodePublicKey(new ChannelDecoder(buffer), me)); if (content == Content.PUBLIC_KEY_SIGNATURE) { message.setHintSign(true); } return true; case EMPTY: case RESERVED1: case RESERVED2: case RESERVED3: default: return true; } }
public Enum<?> updateMeta(PublicKey publicKey, Number640 key, Data newData) { RangeLock<Number640>.Range lock = lock(key); try { if (!securityEntryCheck( key.locationAndDomainAndContentKey(), publicKey, newData.publicKey(), newData.isProtectedEntry())) { return PutStatus.FAILED_SECURITY; } final Data data = backend.get(key); boolean changed = false; if (data != null && newData.publicKey() != null) { data.publicKey(newData.publicKey()); changed = true; } if (data != null && newData.isSigned()) { data.signature(newData.signature()); changed = true; } if (data != null) { data.validFromMillis(newData.validFromMillis()); data.ttlSeconds(newData.ttlSeconds()); changed = true; } if (changed) { long expiration = data.expirationMillis(); // handle timeout backend.addTimeout(key, expiration); // no release of old data, as we just update it backend.put(key, data); return PutStatus.OK; } else { return PutStatus.NOT_FOUND; } } finally { newData.release(); lock.unlock(); } }
public boolean decodePayload(final ByteBuf buf) throws NoSuchAlgorithmException, InvalidKeySpecException, InvalidKeyException { LOG.debug( "About to pass message {} to {}. Buffer to read: {}.", message, message.senderSocket(), buf.readableBytes()); if (!message.hasContent()) { return true; } // payload comes here int size; PublicKey receivedPublicKey; while (contentTypes.size() > 0) { Content content = contentTypes.peek(); LOG.debug("Parse content: {} in message {}", content, message); switch (content) { case INTEGER: if (buf.readableBytes() < Utils.INTEGER_BYTE_SIZE) { return false; } message.intValue(buf.readInt()); lastContent = contentTypes.poll(); break; case LONG: if (buf.readableBytes() < Utils.LONG_BYTE_SIZE) { return false; } message.longValue(buf.readLong()); lastContent = contentTypes.poll(); break; case KEY: if (buf.readableBytes() < Number160.BYTE_ARRAY_SIZE) { return false; } byte[] me = new byte[Number160.BYTE_ARRAY_SIZE]; buf.readBytes(me); message.key(new Number160(me)); lastContent = contentTypes.poll(); break; case BLOOM_FILTER: if (buf.readableBytes() < Utils.SHORT_BYTE_SIZE) { return false; } size = buf.getUnsignedShort(buf.readerIndex()); if (buf.readableBytes() < size) { return false; } message.bloomFilter(new SimpleBloomFilter<Number160>(buf)); lastContent = contentTypes.poll(); break; case SET_NEIGHBORS: if (neighborSize == -1 && buf.readableBytes() < Utils.BYTE_BYTE_SIZE) { return false; } if (neighborSize == -1) { neighborSize = buf.readUnsignedByte(); } if (neighborSet == null) { neighborSet = new NeighborSet(-1, new ArrayList<PeerAddress>(neighborSize)); } for (int i = neighborSet.size(); i < neighborSize; i++) { if (buf.readableBytes() < Utils.SHORT_BYTE_SIZE) { return false; } int header = buf.getUnsignedShort(buf.readerIndex()); size = PeerAddress.size(header); if (buf.readableBytes() < size) { return false; } PeerAddress pa = new PeerAddress(buf); neighborSet.add(pa); } message.neighborsSet(neighborSet); lastContent = contentTypes.poll(); neighborSize = -1; neighborSet = null; break; case SET_PEER_SOCKET: if (peerSocketAddressSize == -1 && buf.readableBytes() < Utils.BYTE_BYTE_SIZE) { return false; } if (peerSocketAddressSize == -1) { peerSocketAddressSize = buf.readUnsignedByte(); } if (peerSocketAddresses == null) { peerSocketAddresses = new ArrayList<PeerSocketAddress>(peerSocketAddressSize); } for (int i = peerSocketAddresses.size(); i < peerSocketAddressSize; i++) { if (buf.readableBytes() < Utils.BYTE_BYTE_SIZE) { return false; } int header = buf.getUnsignedByte(buf.readerIndex()); boolean isIPv4 = header == 0; size = PeerSocketAddress.size(isIPv4); if (buf.readableBytes() < size + Utils.BYTE_BYTE_SIZE) { return false; } // skip the ipv4/ipv6 header buf.skipBytes(1); peerSocketAddresses.add(PeerSocketAddress.create(buf, isIPv4)); } message.peerSocketAddresses(peerSocketAddresses); lastContent = contentTypes.poll(); peerSocketAddressSize = -1; peerSocketAddresses = null; break; case SET_KEY640: if (keyCollectionSize == -1 && buf.readableBytes() < Utils.INTEGER_BYTE_SIZE) { return false; } if (keyCollectionSize == -1) { keyCollectionSize = buf.readInt(); } if (keyCollection == null) { keyCollection = new KeyCollection(new ArrayList<Number640>(keyCollectionSize)); } for (int i = keyCollection.size(); i < keyCollectionSize; i++) { if (buf.readableBytes() < Number160.BYTE_ARRAY_SIZE + Number160.BYTE_ARRAY_SIZE + Number160.BYTE_ARRAY_SIZE + Number160.BYTE_ARRAY_SIZE) { return false; } byte[] me2 = new byte[Number160.BYTE_ARRAY_SIZE]; buf.readBytes(me2); Number160 locationKey = new Number160(me2); buf.readBytes(me2); Number160 domainKey = new Number160(me2); buf.readBytes(me2); Number160 contentKey = new Number160(me2); buf.readBytes(me2); Number160 versionKey = new Number160(me2); keyCollection.add(new Number640(locationKey, domainKey, contentKey, versionKey)); } message.keyCollection(keyCollection); lastContent = contentTypes.poll(); keyCollectionSize = -1; keyCollection = null; break; case MAP_KEY640_DATA: if (mapSize == -1 && buf.readableBytes() < Utils.INTEGER_BYTE_SIZE) { return false; } if (mapSize == -1) { mapSize = buf.readInt(); } if (dataMap == null) { dataMap = new DataMap(new TreeMap<Number640, Data>()); } if (data != null) { if (!data.decodeBuffer(buf)) { return false; } if (!data.decodeDone(buf, message.publicKey(0), signatureFactory)) { return false; } data = null; key = null; } for (int i = dataMap.size(); i < mapSize; i++) { if (key == null) { if (buf.readableBytes() < Number160.BYTE_ARRAY_SIZE + Number160.BYTE_ARRAY_SIZE + Number160.BYTE_ARRAY_SIZE + Number160.BYTE_ARRAY_SIZE) { return false; } byte[] me3 = new byte[Number160.BYTE_ARRAY_SIZE]; buf.readBytes(me3); Number160 locationKey = new Number160(me3); buf.readBytes(me3); Number160 domainKey = new Number160(me3); buf.readBytes(me3); Number160 contentKey = new Number160(me3); buf.readBytes(me3); Number160 versionKey = new Number160(me3); key = new Number640(locationKey, domainKey, contentKey, versionKey); } LOG.debug("Key decoded in message {}, remaining {}", message, buf.readableBytes()); data = Data.decodeHeader(buf, signatureFactory); if (data == null) { return false; } LOG.debug("Header decoded in message {}, remaining {}", message, buf.readableBytes()); dataMap.dataMap().put(key, data); if (!data.decodeBuffer(buf)) { return false; } LOG.debug("Buffer decoded in message {}", message); if (!data.decodeDone(buf, message.publicKey(0), signatureFactory)) { return false; } LOG.debug("Done decoded in message {}", message); // if we have signed the message, set the public key anyway, but only if we indicated so inheritPublicKey(message, data); data = null; key = null; } message.setDataMap(dataMap); lastContent = contentTypes.poll(); mapSize = -1; dataMap = null; break; case MAP_KEY640_KEYS: if (keyMap640KeysSize == -1 && buf.readableBytes() < Utils.INTEGER_BYTE_SIZE) { return false; } if (keyMap640KeysSize == -1) { keyMap640KeysSize = buf.readInt(); } if (keyMap640Keys == null) { keyMap640Keys = new KeyMap640Keys(new TreeMap<Number640, Collection<Number160>>()); } final int meta = Number160.BYTE_ARRAY_SIZE + Number160.BYTE_ARRAY_SIZE + Number160.BYTE_ARRAY_SIZE + Number160.BYTE_ARRAY_SIZE; for (int i = keyMap640Keys.size(); i < keyMap640KeysSize; i++) { if (buf.readableBytes() < meta + Utils.BYTE_BYTE_SIZE) { return false; } size = buf.getUnsignedByte(buf.readerIndex() + meta); if (buf.readableBytes() < meta + Utils.BYTE_BYTE_SIZE + (size * Number160.BYTE_ARRAY_SIZE)) { return false; } byte[] me3 = new byte[Number160.BYTE_ARRAY_SIZE]; buf.readBytes(me3); Number160 locationKey = new Number160(me3); buf.readBytes(me3); Number160 domainKey = new Number160(me3); buf.readBytes(me3); Number160 contentKey = new Number160(me3); buf.readBytes(me3); Number160 versionKey = new Number160(me3); int numBasedOn = buf.readByte(); Set<Number160> value = new HashSet<Number160>(numBasedOn); for (int j = 0; j < numBasedOn; j++) { buf.readBytes(me3); Number160 basedOnKey = new Number160(me3); value.add(basedOnKey); } keyMap640Keys.put(new Number640(locationKey, domainKey, contentKey, versionKey), value); } message.keyMap640Keys(keyMap640Keys); lastContent = contentTypes.poll(); keyMap640KeysSize = -1; keyMap640Keys = null; break; case MAP_KEY640_BYTE: if (keyMapByteSize == -1 && buf.readableBytes() < Utils.INTEGER_BYTE_SIZE) { return false; } if (keyMapByteSize == -1) { keyMapByteSize = buf.readInt(); } if (keyMapByte == null) { keyMapByte = new KeyMapByte(new HashMap<Number640, Byte>(2 * keyMapByteSize)); } for (int i = keyMapByte.size(); i < keyMapByteSize; i++) { if (buf.readableBytes() < Number160.BYTE_ARRAY_SIZE + Number160.BYTE_ARRAY_SIZE + Number160.BYTE_ARRAY_SIZE + Number160.BYTE_ARRAY_SIZE + 1) { return false; } byte[] me3 = new byte[Number160.BYTE_ARRAY_SIZE]; buf.readBytes(me3); Number160 locationKey = new Number160(me3); buf.readBytes(me3); Number160 domainKey = new Number160(me3); buf.readBytes(me3); Number160 contentKey = new Number160(me3); buf.readBytes(me3); Number160 versionKey = new Number160(me3); byte value = buf.readByte(); keyMapByte.put(new Number640(locationKey, domainKey, contentKey, versionKey), value); } message.keyMapByte(keyMapByte); lastContent = contentTypes.poll(); keyMapByteSize = -1; keyMapByte = null; break; case BYTE_BUFFER: if (bufferSize == -1 && buf.readableBytes() < Utils.INTEGER_BYTE_SIZE) { return false; } if (bufferSize == -1) { bufferSize = buf.readInt(); } if (buffer == null) { buffer = new DataBuffer(); } final int remaining = bufferSize - bufferTransferred; bufferTransferred += buffer.transferFrom(buf, remaining); if (bufferTransferred < bufferSize) { LOG.debug( "Still looking for data. Indicating that its not finished yet. Already Transferred = {}, Size = {}.", bufferTransferred, bufferSize); return false; } message.buffer(new Buffer(buffer.toByteBuf(), bufferSize)); lastContent = contentTypes.poll(); bufferSize = -1; bufferTransferred = 0; buffer = null; break; case SET_TRACKER_DATA: if (trackerDataSize == -1 && buf.readableBytes() < Utils.BYTE_BYTE_SIZE) { return false; } if (trackerDataSize == -1) { trackerDataSize = buf.readUnsignedByte(); } if (trackerData == null) { trackerData = new TrackerData(new HashMap<PeerAddress, Data>(2 * trackerDataSize)); } if (currentTrackerData != null) { if (!currentTrackerData.decodeBuffer(buf)) { return false; } if (!currentTrackerData.decodeDone(buf, message.publicKey(0), signatureFactory)) { return false; } currentTrackerData = null; } for (int i = trackerData.size(); i < trackerDataSize; i++) { if (buf.readableBytes() < Utils.SHORT_BYTE_SIZE) { return false; } int header = buf.getUnsignedShort(buf.readerIndex()); size = PeerAddress.size(header); if (buf.readableBytes() < size) { return false; } PeerAddress pa = new PeerAddress(buf); currentTrackerData = Data.decodeHeader(buf, signatureFactory); if (currentTrackerData == null) { return false; } trackerData.peerAddresses().put(pa, currentTrackerData); if (message.isSign()) { currentTrackerData.publicKey(message.publicKey(0)); } if (!currentTrackerData.decodeBuffer(buf)) { return false; } if (!currentTrackerData.decodeDone(buf, message.publicKey(0), signatureFactory)) { return false; } currentTrackerData = null; } message.trackerData(trackerData); lastContent = contentTypes.poll(); trackerDataSize = -1; trackerData = null; break; case PUBLIC_KEY: // fall-through case PUBLIC_KEY_SIGNATURE: receivedPublicKey = signatureFactory.decodePublicKey(buf); if (content == Content.PUBLIC_KEY_SIGNATURE) { if (receivedPublicKey == PeerBuilder.EMPTY_PUBLIC_KEY) { throw new InvalidKeyException("The public key cannot be empty."); } } if (receivedPublicKey == null) { return false; } message.publicKey(receivedPublicKey); lastContent = contentTypes.poll(); break; default: break; } } LOG.debug("Parsed content in message {}", message); if (message.isSign()) { size = signatureFactory.signatureSize(); if (buf.readableBytes() < size) { return false; } SignatureCodec signatureEncode = signatureFactory.signatureCodec(buf); message.receivedSignature(signatureEncode); } return true; }