Example #1
0
 public Message SetKeyMapByte(KeyMapByte keyMapByte)
 {
     if (!_presetContentTypes)
     {
         SetContentType(Content.MapKey640Byte);
     }
     if (_keyMapByteList == null) {
         _keyMapByteList = new List<KeyMapByte>(1);
     }
     _keyMapByteList.Add(keyMapByte);
     return this;
 }
Example #2
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;
        }