Ejemplo n.º 1
0
        /// <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);
        }
Ejemplo n.º 2
0
 public MessageContentIndex(int index, Message.Content content)
 {
     Index   = index;
     Content = content;
 }
Ejemplo n.º 3
0
 public MessageContentIndex(int index, Message.Content content)
 {
     Index = index;
     Content = content;
 }
Ejemplo n.º 4
0
        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);
        }
Ejemplo n.º 5
0
        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;
        }
Ejemplo n.º 6
0
        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);
        }
Ejemplo n.º 7
0
 /// <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;
 }