public static Data DeocdeHeader(AlternativeCompositeByteBuf buffer, ISignatureFactory signatureFactory) { // 2 is the smallest packet size, we could start if we know 1 byte to // decode the header, but we always need a second byte. Thus, we are waiting for at least 2 bytes. if (buffer.ReadableBytes < 2 * Utils.Utils.ByteByteSize) { return(null); } int header = buffer.GetUByte(buffer.ReaderIndex); DataType type = Type(header); // length int length; int indexLength = Utils.Utils.ByteByteSize; int indexTtl; switch (type) { case DataType.Small: length = buffer.GetUByte(buffer.ReaderIndex + indexLength); indexTtl = indexLength + Utils.Utils.ByteByteSize; break; case DataType.Large: indexTtl = indexLength + Utils.Utils.IntegerByteSize; if (buffer.ReadableBytes < indexTtl) { return(null); } length = buffer.GetInt(buffer.ReaderIndex + indexLength); break; default: throw new ArgumentException("Unknown DataType."); } // TTL int ttl; int indexBasedOnNr; if (CheckHasTtl(header)) { indexBasedOnNr = indexTtl + Utils.Utils.IntegerByteSize; if (buffer.ReadableBytes < indexBasedOnNr) { return(null); } ttl = buffer.GetInt(buffer.ReaderIndex + indexTtl); } else { indexBasedOnNr = indexTtl; ttl = -1; } // nr basedOn + basedOn int numBasedOn; int indexPublicKeySize; int indexBasedOn; var basedOn = new List <Number160>(); if (CheckHasBasedOn(header)) { // get nr of basedOn keys indexBasedOn = indexBasedOnNr + Utils.Utils.ByteByteSize; if (buffer.ReadableBytes < indexBasedOn) { return(null); } numBasedOn = buffer.GetUByte(buffer.ReaderIndex + indexBasedOn) + 1; indexPublicKeySize = indexBasedOn + (numBasedOn * Number160.ByteArraySize); if (buffer.ReadableBytes < indexPublicKeySize) { return(null); } // get basedOn int index = buffer.ReaderIndex + indexBasedOnNr + Utils.Utils.ByteByteSize; var me = new sbyte[Number160.ByteArraySize]; for (int i = 0; i < numBasedOn; i++) { buffer.GetBytes(index, me); index += Number160.ByteArraySize; basedOn.Add(new Number160(me)); } } else { indexPublicKeySize = indexBasedOnNr; numBasedOn = 0; } // public key + size int publicKeySize; int indexPublicKey; int indexEnd; IPublicKey publicKey; if (CheckHasPublicKey(header)) { // get public key size indexPublicKey = indexPublicKeySize + Utils.Utils.ShortByteSize; if (buffer.ReadableBytes < indexPublicKey) { return(null); } publicKeySize = buffer.GetUShort(buffer.ReaderIndex + indexPublicKeySize); indexEnd = indexPublicKey + publicKeySize; if (buffer.ReadableBytes < indexEnd) { return(null); } // get public key buffer.SkipBytes(indexPublicKeySize); publicKey = signatureFactory.DecodePublicKey(buffer); } else { publicKeySize = 0; indexPublicKey = indexPublicKeySize; buffer.SkipBytes(indexPublicKey); publicKey = null; } // now, we have read the header and the length var data = new Data(header, length); data.TtlSeconds = ttl; data.BasedOnSet = basedOn; data.PublicKey = publicKey; return(data); }
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); }