/// <summary> /// Decodes the 8 content types from an integer (32 bit). /// </summary> /// <param name="contentTypes">The 8 content types to be decoded.</param> /// <param name="message">The decoded content types.</param> /// <returns></returns> public static Message.Content[] DecodeContentTypes(int contentTypes, Message message) { var result = new Message.Content[Message.ContentTypeLength]; for (int i = 0; i < Message.ContentTypeLength; i++) { var content = (Message.Content)(contentTypes & Utils.Utils.Mask0F); result[i] = content; if (content == Message.Content.PublicKeySignature) { message.SetHintSign(); } contentTypes >>= 4; } return(result); }
public MessageContentIndex(int index, Message.Content content) { Index = index; Content = content; }
private bool Loop(AlternativeCompositeByteBuf buffer) { MessageContentIndex next; while ((next = Message.ContentReferences.Peek2()) != null) { long start = buffer.WriterIndex; Message.Content content = next.Content; switch (content) { case Message.Content.Key: buffer.WriteBytes(Message.Key(next.Index).ToByteArray()); Message.ContentReferences.Dequeue(); break; case Message.Content.Integer: buffer.WriteInt(Message.IntAt(next.Index)); Message.ContentReferences.Dequeue(); break; case Message.Content.Long: buffer.WriteLong(Message.LongAt(next.Index)); Message.ContentReferences.Dequeue(); break; case Message.Content.SetNeighbors: var neighborSet = Message.NeighborsSet(next.Index); // write length buffer.WriteByte((sbyte)neighborSet.Size); foreach (var neighbor in neighborSet.Neighbors) { buffer.WriteBytes(neighbor.ToByteArray()); } Message.ContentReferences.Dequeue(); break; case Message.Content.SetPeerSocket: var list = Message.PeerSocketAddresses; // write length buffer.WriteByte((sbyte)list.Count); foreach (var psa in list) { // write IP version flag buffer.WriteByte(psa.IsIPv4 ? 0 : 1); buffer.WriteBytes(psa.ToByteArray()); } Message.ContentReferences.Dequeue(); break; case Message.Content.BloomFilter: var bf = Message.BloomFilter(next.Index); bf.ToByteBuffer(buffer); Message.ContentReferences.Dequeue(); break; case Message.Content.SetKey640: var keys = Message.KeyCollection(next.Index); // write length buffer.WriteInt(keys.Size); if (keys.IsConvert) { foreach (var key in keys.KeysConvert) { buffer.WriteBytes(keys.LocationKey.ToByteArray()); buffer.WriteBytes(keys.DomainKey.ToByteArray()); buffer.WriteBytes(key.ToByteArray()); buffer.WriteBytes(keys.VersionKey.ToByteArray()); } } else { foreach (var key in keys.Keys) { buffer.WriteBytes(key.LocationKey.ToByteArray()); buffer.WriteBytes(key.DomainKey.ToByteArray()); buffer.WriteBytes(key.ContentKey.ToByteArray()); buffer.WriteBytes(key.VersionKey.ToByteArray()); } } Message.ContentReferences.Dequeue(); break; case Message.Content.MapKey640Data: var dm = Message.DataMap(next.Index); // write length buffer.WriteInt(dm.Size); if (dm.IsConvert) { foreach (var data in dm.DataMapConvert) { buffer.WriteBytes(dm.LocationKey.ToByteArray()); buffer.WriteBytes(dm.DomainKey.ToByteArray()); buffer.WriteBytes(data.Key.ToByteArray()); buffer.WriteBytes(dm.VersionKey.ToByteArray()); EncodeData(buffer, data.Value, dm.IsConvertMeta, !Message.IsRequest()); } } else { foreach (var data in dm.BackingDataMap) { buffer.WriteBytes(data.Key.LocationKey.ToByteArray()); buffer.WriteBytes(data.Key.DomainKey.ToByteArray()); buffer.WriteBytes(data.Key.ContentKey.ToByteArray()); buffer.WriteBytes(data.Key.VersionKey.ToByteArray()); EncodeData(buffer, data.Value, dm.IsConvertMeta, !Message.IsRequest()); } } Message.ContentReferences.Dequeue(); break; case Message.Content.MapKey640Keys: var kmk = Message.KeyMap640Keys(next.Index); // write length buffer.WriteInt(kmk.Size); foreach (var data in kmk.KeysMap) { buffer.WriteBytes(data.Key.LocationKey.ToByteArray()); buffer.WriteBytes(data.Key.DomainKey.ToByteArray()); buffer.WriteBytes(data.Key.ContentKey.ToByteArray()); buffer.WriteBytes(data.Key.VersionKey.ToByteArray()); // write number of based-on keys buffer.WriteByte((sbyte)data.Value.Count); // write based-on keys foreach (var key in data.Value) { buffer.WriteBytes(key.ToByteArray()); } } Message.ContentReferences.Dequeue(); break; case Message.Content.MapKey640Byte: var kmb = Message.KeyMapByte(next.Index); // write length buffer.WriteInt(kmb.Size); foreach (var data in kmb.KeysMap) { buffer.WriteBytes(data.Key.LocationKey.ToByteArray()); buffer.WriteBytes(data.Key.DomainKey.ToByteArray()); buffer.WriteBytes(data.Key.ContentKey.ToByteArray()); buffer.WriteBytes(data.Key.VersionKey.ToByteArray()); // write byte buffer.WriteByte(data.Value); } Message.ContentReferences.Dequeue(); break; case Message.Content.ByteBuffer: var b = Message.Buffer(next.Index); if (!_resume) { buffer.WriteInt(b.Length); } // write length int readable = b.Readable; buffer.WriteBytes(b.BackingBuffer, readable); if (b.IncRead(readable) == b.Length) { Message.ContentReferences.Dequeue(); } else if (Message.IsStreaming()) { Logger.Debug("Partial message of length {0} sent.", readable); return(false); } else { const string description = "Larger buffer has been announced, but not in message streaming mode. This is wrong."; Logger.Error(description); throw new SystemException(description); } break; case Message.Content.SetTrackerData: var td = Message.TrackerData(next.Index); // write length buffer.WriteByte((sbyte)td.PeerAddresses.Count); // TODO remove cast foreach (var data in td.PeerAddresses) { var me = data.Key.ToByteArray(); buffer.WriteBytes(me); var d = data.Value.Duplicate(); EncodeData(buffer, d, false, !Message.IsRequest()); } Message.ContentReferences.Dequeue(); break; case Message.Content.PublicKeySignature: // flag to encode public key Message.SetHintSign(); // then, do the regular public key stuff -> no break goto case Message.Content.PublicKey; // TODO check, else duplicate code case Message.Content.PublicKey: var pk = Message.PublicKey(next.Index); _signatureFactory.EncodePublicKey(pk, buffer); Message.ContentReferences.Dequeue(); break; default: throw new SystemException("Unknown type: " + next.Content); } Logger.Debug("Wrote in encoder for {0} {1}.", content, buffer.WriterIndex - start); } return(true); }
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; }
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); }
/// <summary> /// Decodes the 8 content types from an integer (32 bit). /// </summary> /// <param name="contentTypes">The 8 content types to be decoded.</param> /// <param name="message">The decoded content types.</param> /// <returns></returns> public static Message.Content[] DecodeContentTypes(int contentTypes, Message message) { var result = new Message.Content[Message.ContentTypeLength]; for (int i = 0; i < Message.ContentTypeLength; i++) { var content = (Message.Content) (contentTypes & Utils.Utils.Mask0F); result[i] = content; if (content == Message.Content.PublicKeySignature) { message.SetHintSign(); } contentTypes >>= 4; } return result; }