private bool DecodePayload(AlternativeCompositeByteBuf buffer) { Logger.Debug("About to pass message {0} to {1}. Buffer to read: {2}.", Message, Message.SenderSocket, buffer.ReadableBytes); if (!Message.HasContent()) { return(true); } int size; IPublicKey receivedPublicKey; while (_contentTypes.Count > 0) { Message.Content content = _contentTypes.Peek(); Logger.Debug("Go for content: {0}.", content); switch (content) { case Message.Content.Integer: if (buffer.ReadableBytes < Utils.Utils.IntegerByteSize) { return(false); } Message.SetIntValue(buffer.ReadInt()); LastContent = _contentTypes.Dequeue(); break; case Message.Content.Long: if (buffer.ReadableBytes < Utils.Utils.LongByteSize) { return(false); } Message.SetLongValue(buffer.ReadLong()); LastContent = _contentTypes.Dequeue(); break; case Message.Content.Key: if (buffer.ReadableBytes < Number160.ByteArraySize) { return(false); } var keyBytes = new sbyte[Number160.ByteArraySize]; buffer.ReadBytes(keyBytes); Message.SetKey(new Number160(keyBytes)); LastContent = _contentTypes.Dequeue(); break; case Message.Content.BloomFilter: if (buffer.ReadableBytes < Utils.Utils.ShortByteSize) { return(false); } size = buffer.GetUShort(buffer.ReaderIndex); if (buffer.ReadableBytes < size) { return(false); } Message.SetBloomFilter(new SimpleBloomFilter <Number160>(buffer)); LastContent = _contentTypes.Dequeue(); break; case Message.Content.SetNeighbors: if (_neighborSize == -1 && buffer.ReadableBytes < Utils.Utils.ByteByteSize) { return(false); } if (_neighborSize == -1) { _neighborSize = buffer.ReadByte(); } if (_neighborSet == null) { _neighborSet = new NeighborSet(-1, new List <PeerAddress>(_neighborSize)); } for (int i = _neighborSet.Size; i < _neighborSize; i++) { if (buffer.ReadableBytes < Utils.Utils.ShortByteSize) { return(false); } int header = buffer.GetUShort(buffer.ReaderIndex); size = PeerAddress.CalculateSize(header); if (buffer.ReadableBytes < size) { return(false); } var pa = new PeerAddress(buffer); _neighborSet.Add(pa); } Message.SetNeighborSet(_neighborSet); LastContent = _contentTypes.Dequeue(); _neighborSize = -1; // TODO why here? not in prepareFinish()? _neighborSet = null; break; case Message.Content.SetPeerSocket: if (_peerSocketAddressSize == -1 && buffer.ReadableBytes < Utils.Utils.ByteByteSize) { return(false); } if (_peerSocketAddressSize == -1) { _peerSocketAddressSize = buffer.ReadUByte(); } if (_peerSocketAddresses == null) { _peerSocketAddresses = new List <PeerSocketAddress>(_peerSocketAddressSize); } for (int i = _peerSocketAddresses.Count; i < _peerSocketAddressSize; i++) { if (buffer.ReadableBytes < Utils.Utils.ByteByteSize) { return(false); } int header = buffer.GetUByte(buffer.ReaderIndex); bool isIPv4 = header == 0; // TODO check if works size = PeerSocketAddress.Size(isIPv4); if (buffer.ReadableBytes < size + Utils.Utils.ByteByteSize) { return(false); } // skip the ipv4/ipv6 header buffer.SkipBytes(1); _peerSocketAddresses.Add(PeerSocketAddress.Create(buffer, isIPv4)); } Message.SetPeerSocketAddresses(_peerSocketAddresses); LastContent = _contentTypes.Dequeue(); _peerSocketAddressSize = -1; // TODO why here? not in prepareFinish()? _peerSocketAddresses = null; break; case Message.Content.SetKey640: if (_keyCollectionSize == -1 && buffer.ReadableBytes < Utils.Utils.IntegerByteSize) { return(false); } if (_keyCollectionSize == -1) { _keyCollectionSize = buffer.ReadInt(); } if (_keyCollection == null) { _keyCollection = new KeyCollection(new List <Number640>(_keyCollectionSize)); } for (int i = _keyCollection.Size; i < _keyCollectionSize; i++) { if (buffer.ReadableBytes < 4 * Number160.ByteArraySize) { return(false); } var me = new sbyte[Number160.ByteArraySize]; buffer.ReadBytes(me); var locationKey = new Number160(me); buffer.ReadBytes(me); var domainKey = new Number160(me); buffer.ReadBytes(me); var contentKey = new Number160(me); buffer.ReadBytes(me); var versionKey = new Number160(me); _keyCollection.Add(new Number640(locationKey, domainKey, contentKey, versionKey)); } Message.SetKeyCollection(_keyCollection); LastContent = _contentTypes.Dequeue(); _keyCollectionSize = -1; // TODO why here? not in prepareFinish()? _keyCollection = null; break; case Message.Content.MapKey640Data: if (_mapSize == -1 && buffer.ReadableBytes < Utils.Utils.IntegerByteSize) { return(false); } if (_mapSize == -1) { _mapSize = buffer.ReadInt(); } if (_dataMap == null) { _dataMap = new DataMap(new Dictionary <Number640, Data>(2 * _mapSize)); } if (_data != null) { if (!_data.DecodeBuffer(buffer)) { return(false); } if (!_data.DecodeDone(buffer, Message.PublicKey(0), _signatureFactory)) { return(false); } _data = null; // TODO why here? not in prepareFinish()? _key = null; } for (int i = _dataMap.Size; i < _mapSize; i++) { if (_key == null) { if (buffer.ReadableBytes < 4 * Number160.ByteArraySize) { return(false); } var me = new sbyte[Number160.ByteArraySize]; buffer.ReadBytes(me); var locationKey = new Number160(me); buffer.ReadBytes(me); var domainKey = new Number160(me); buffer.ReadBytes(me); var contentKey = new Number160(me); buffer.ReadBytes(me); var versionKey = new Number160(me); _key = new Number640(locationKey, domainKey, contentKey, versionKey); } _data = Data.DeocdeHeader(buffer, _signatureFactory); if (_data == null) { return(false); } _dataMap.BackingDataMap.Add(_key, _data); if (!_data.DecodeBuffer(buffer)) { return(false); } if (!_data.DecodeDone(buffer, Message.PublicKey(0), _signatureFactory)) { return(false); } // if we have signed the message, set the public key anyway, but only if we indicated so if (Message.IsSign && Message.PublicKey(0) != null && _data.HasPublicKey && (_data.PublicKey == null || _data.PublicKey == PeerBuilder.EmptyPublicKey)) // TODO check empty key condition { _data.SetPublicKey(Message.PublicKey(0)); } _data = null; // TODO why here? not in prepareFinish()? _key = null; } Message.SetDataMap(_dataMap); LastContent = _contentTypes.Dequeue(); _mapSize = -1; // TODO why here? not in prepareFinish()? _dataMap = null; break; case Message.Content.MapKey640Keys: if (_keyMap640KeysSize == -1 && buffer.ReadableBytes < Utils.Utils.IntegerByteSize) { return(false); } if (_keyMap640KeysSize == -1) { _keyMap640KeysSize = buffer.ReadInt(); } if (_keyMap640Keys == null) { _keyMap640Keys = new KeyMap640Keys(new SortedDictionary <Number640, ICollection <Number160> >()); // TODO check TreeMap equivalent } const int meta = 4 * Number160.ByteArraySize; for (int i = _keyMap640Keys.Size; i < _keyMap640KeysSize; i++) { if (buffer.ReadableBytes < meta + Utils.Utils.ByteByteSize) { return(false); } size = buffer.GetUByte(buffer.ReaderIndex + meta); if (buffer.ReadableBytes < meta + Utils.Utils.ByteByteSize + (size * Number160.ByteArraySize)) { return(false); } var me = new sbyte[Number160.ByteArraySize]; buffer.ReadBytes(me); var locationKey = new Number160(me); buffer.ReadBytes(me); var domainKey = new Number160(me); buffer.ReadBytes(me); var contentKey = new Number160(me); buffer.ReadBytes(me); var versionKey = new Number160(me); int numBasedOn = buffer.ReadByte(); var value = new HashSet <Number160>(); for (int j = 0; j < numBasedOn; j++) { buffer.ReadBytes(me); var basedOnKey = new Number160(me); value.Add(basedOnKey); } _keyMap640Keys.Put(new Number640(locationKey, domainKey, contentKey, versionKey), value); } Message.SetKeyMap640Keys(_keyMap640Keys); LastContent = _contentTypes.Dequeue(); _keyMap640KeysSize = -1; // TODO why here? not in prepareFinish()? _keyMap640Keys = null; break; case Message.Content.MapKey640Byte: if (_keyMapByteSize == -1 && buffer.ReadableBytes < Utils.Utils.IntegerByteSize) { return(false); } if (_keyMapByteSize == -1) { _keyMapByteSize = buffer.ReadInt(); } if (_keyMapByte == null) { _keyMapByte = new KeyMapByte(new Dictionary <Number640, sbyte>(2 * _keyMapByteSize)); } for (int i = _keyMapByte.Size; i < _keyMapByteSize; i++) { if (buffer.ReadableBytes < 4 * Number160.ByteArraySize + 1) { return(false); } var me = new sbyte[Number160.ByteArraySize]; buffer.ReadBytes(me); var locationKey = new Number160(me); buffer.ReadBytes(me); var domainKey = new Number160(me); buffer.ReadBytes(me); var contentKey = new Number160(me); buffer.ReadBytes(me); var versionKey = new Number160(me); sbyte value = buffer.ReadByte(); _keyMapByte.Put(new Number640(locationKey, domainKey, contentKey, versionKey), value); } Message.SetKeyMapByte(_keyMapByte); LastContent = _contentTypes.Dequeue(); _keyMapByteSize = -1; // TODO why here? not in prepareFinish()? _keyMapByte = null; break; case Message.Content.ByteBuffer: if (_bufferSize == -1 && buffer.ReadableBytes < Utils.Utils.IntegerByteSize) { return(false); } if (_bufferSize == -1) { _bufferSize = buffer.ReadInt(); } if (_buffer == null) { _buffer = new DataBuffer(); } int already = _buffer.AlreadyTransferred; int remaining = _bufferSize - already; // already finished if (remaining != 0) { int read = _buffer.TransferFrom(buffer, remaining); if (read != remaining) { Logger.Debug( "Still looking for data. Indicating that its not finished yet. Already Transferred = {0}, Size = {1}.", _buffer.AlreadyTransferred, _bufferSize); return(false); } } ByteBuf buf2 = AlternativeCompositeByteBuf.CompBuffer(_buffer.ToByteBufs()); Message.SetBuffer(new Buffer(buf2, _bufferSize)); LastContent = _contentTypes.Dequeue(); _bufferSize = -1; _buffer = null; break; case Message.Content.SetTrackerData: if (_trackerDataSize == -1 && buffer.ReadableBytes < Utils.Utils.ByteByteSize) { return(false); } if (_trackerDataSize == -1) { _trackerDataSize = buffer.ReadUByte(); } if (_trackerData == null) { _trackerData = new TrackerData(new Dictionary <PeerAddress, Data>(2 * _trackerDataSize)); } if (_currentTrackerData != null) { if (!_currentTrackerData.DecodeBuffer(buffer)) { return(false); } if (!_currentTrackerData.DecodeDone(buffer, Message.PublicKey(0), _signatureFactory)) { return(false); } _currentTrackerData = null; } for (int i = _trackerData.Size; i < _trackerDataSize; i++) { if (buffer.ReadableBytes < Utils.Utils.ShortByteSize) { return(false); } int header = buffer.GetUShort(buffer.ReaderIndex); size = PeerAddress.CalculateSize(header); if (buffer.ReadableBytes < Utils.Utils.ShortByteSize) { return(false); } var pa = new PeerAddress(buffer); _currentTrackerData = Data.DeocdeHeader(buffer, _signatureFactory); if (_currentTrackerData == null) { return(false); } _trackerData.PeerAddresses.Add(pa, _currentTrackerData); if (Message.IsSign) { _currentTrackerData.SetPublicKey(Message.PublicKey(0)); } if (!_currentTrackerData.DecodeBuffer(buffer)) { return(false); } if (!_currentTrackerData.DecodeDone(buffer, Message.PublicKey(0), _signatureFactory)) { return(false); } _currentTrackerData = null; // TODO why here? } Message.SetTrackerData(_trackerData); LastContent = _contentTypes.Dequeue(); _trackerDataSize = -1; _trackerData = null; break; case Message.Content.PublicKey: // fall-through case Message.Content.PublicKeySignature: receivedPublicKey = _signatureFactory.DecodePublicKey(buffer); if (content == Message.Content.PublicKeySignature) { if (receivedPublicKey == PeerBuilder.EmptyPublicKey) // TODO check if works { // TODO throw InvalidKeyException throw new SystemException("The public key cannot be empty."); } } if (receivedPublicKey == null) { return(false); } Message.SetPublicKey(receivedPublicKey); LastContent = _contentTypes.Dequeue(); break; default: break; } } if (Message.IsSign) { var signatureEncode = _signatureFactory.SignatureCodec; size = signatureEncode.SignatureSize; if (buffer.ReadableBytes < size) { return(false); } signatureEncode.Read(buffer); Message.SetReceivedSignature(signatureEncode); } return(true); }