Ejemplo n.º 1
0
 public Message SetNeighborSet(NeighborSet neighborSet)
 {
     if (!_presetContentTypes)
     {
         SetContentType(Content.SetNeighbors);
     }
     if (_neighborsList == null)
     {
         _neighborsList = new List<NeighborSet>(1);
     }
     _neighborsList.Add(neighborSet);
     return this;
 }
Ejemplo n.º 2
0
        public override void HandleResponse(Message.Message requestMessage, PeerConnection peerConnection, bool sign, IResponder responder)
        {
            if (requestMessage.KeyList.Count < 2)
            {
                throw new ArgumentException("At least location and domain keys are needed.");
            }
            if (!(requestMessage.Type == Message.Message.MessageType.Request1 ||
                  requestMessage.Type == Message.Message.MessageType.Request2 ||
                  requestMessage.Type == Message.Message.MessageType.Request3 ||
                  requestMessage.Type == Message.Message.MessageType.Request4) &&
                (requestMessage.Command == Rpc.Commands.Neighbor.GetNr()))
            {
                throw new ArgumentException("Message content is wrong for this handler.");
            }

            Number160 locationKey = requestMessage.Key(0);
            Number160 domainKey   = requestMessage.Key(1);

            var neighbors = GetNeighbors(locationKey, NeighborSize);

            if (neighbors == null)
            {
                // return empty neighbor set
                var response = CreateResponseMessage(requestMessage, Message.Message.MessageType.NotFound);
                response.SetNeighborSet(new NeighborSet(-1, new Collection <PeerAddress>()));
                responder.Response(response);
                return;
            }

            // create response message and set neighbors
            var responseMessage = CreateResponseMessage(requestMessage, Message.Message.MessageType.Ok);

            Logger.Debug("Found the following neighbors: {0}.", Convenient.ToString(neighbors));
            var neighborSet = new NeighborSet(NeighborLimit, neighbors);

            responseMessage.SetNeighborSet(neighborSet);

            Number160 contentKey         = requestMessage.Key(2);
            var       keyBloomFilter     = requestMessage.BloomFilter(0);
            var       contentBloomFilter = requestMessage.BloomFilter(1);
            var       keyCollection      = requestMessage.KeyCollection(0);

            // it is important to set an integer if a value is present
            bool isDigest = requestMessage.Type != Message.Message.MessageType.Request1;

            if (isDigest)
            {
                if (requestMessage.Type == Message.Message.MessageType.Request2)
                {
                    DigestInfo digestInfo;
                    if (PeerBean.DigestStorage == null)
                    {
                        // no storage to search
                        digestInfo = new DigestInfo();
                    }
                    else if (contentKey != null && locationKey != null && domainKey != null)
                    {
                        var locationAndDomainKey = new Number320(locationKey, domainKey);
                        var from = new Number640(locationAndDomainKey, contentKey, Number160.Zero);
                        var to   = new Number640(locationAndDomainKey, contentKey, Number160.MaxValue);
                        digestInfo = PeerBean.DigestStorage.Digest(from, to, -1, true);
                    }
                    else if ((keyBloomFilter != null || contentBloomFilter != null) && locationKey != null && domainKey != null)
                    {
                        var locationAndDomainKey = new Number320(locationKey, domainKey);
                        digestInfo = PeerBean.DigestStorage.Digest(locationAndDomainKey, keyBloomFilter,
                                                                   contentBloomFilter, -1, true, true);
                    }
                    else if (keyCollection != null && keyCollection.Keys.Count == 2)
                    {
                        var enumerator = keyCollection.Keys.GetEnumerator();
                        var from       = enumerator.MoveNext() ? enumerator.Current : null; // TODO works correctly?
                        var to         = enumerator.MoveNext() ? enumerator.Current : null;

                        digestInfo = PeerBean.DigestStorage.Digest(from, to, -1, true);
                    }
                    else if (locationKey != null && domainKey != null)
                    {
                        var locationAndDomainKey = new Number320(locationKey, domainKey);
                        var from = new Number640(locationAndDomainKey, Number160.Zero, Number160.Zero);
                        var to   = new Number640(locationAndDomainKey, Number160.MaxValue, Number160.MaxValue);
                        digestInfo = PeerBean.DigestStorage.Digest(from, to, -1, true);
                    }
                    else
                    {
                        Logger.Warn("Did not search for anything.");
                        digestInfo = new DigestInfo();
                    }
                    responseMessage.SetIntValue(digestInfo.Size);
                    responseMessage.SetKey(digestInfo.KeyDigest);
                    responseMessage.SetKey(digestInfo.ContentDigest);
                }
                else if (requestMessage.Type == Message.Message.MessageType.Request3)
                {
                    DigestInfo digestInfo;
                    if (PeerBean.DigestTracker == null)
                    {
                        // no tracker to search
                        digestInfo = new DigestInfo();
                    }
                    else
                    {
                        digestInfo = PeerBean.DigestTracker.Digest(locationKey, domainKey, contentKey);
                        if (digestInfo.Size == 0)
                        {
                            Logger.Debug("No entry found on peer {0}.", requestMessage.Recipient);
                        }
                    }
                    responseMessage.SetIntValue(digestInfo.Size);
                }
                else if (requestMessage.Type == Message.Message.MessageType.Request4)
                {
                    lock (PeerBean.PeerStatusListeners)
                    {
                        foreach (var listener in PeerBean.PeerStatusListeners)
                        {
                            listener.PeerFailed(requestMessage.Sender,
                                                new PeerException(PeerException.AbortCauseEnum.Shutdown, "shutdown"));
                        }
                    }
                }
            }

            responder.Response(responseMessage);
        }
Ejemplo n.º 3
0
        public Message PrepareFinish()
        {
            Message ret = Message;
            Message.SetDone();

            _contentTypes.Clear();
            Message = null;
            _neighborSize = -1;
            _neighborSet = null;
            // TODO set peerSocketAddressSize/peerSocketAddresses -1/null?
            _keyCollectionSize = -1;
            _keyCollection = null;
            _mapSize = -1;
            _dataMap = null;
            _data = null;
            // TODO set _key to null?
            _keyMap640KeysSize = -1;
            _keyMap640Keys = null;
            // TODO set _keyMapBytesSize/list to -1/null?
            _bufferSize = -1;
            _buffer = null;
            // TODO set _trackerDataSize/list to -1/null?
            // TODO set _signatureFactory to null?

            return ret;
        }
Ejemplo n.º 4
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.º 5
0
        public override void HandleResponse(Message.Message requestMessage, PeerConnection peerConnection, bool sign, IResponder responder)
        {
            if (requestMessage.KeyList.Count < 2)
            {
                throw new ArgumentException("At least location and domain keys are needed.");
            }
            if (!(requestMessage.Type == Message.Message.MessageType.Request1
                || requestMessage.Type == Message.Message.MessageType.Request2
                || requestMessage.Type == Message.Message.MessageType.Request3
                || requestMessage.Type == Message.Message.MessageType.Request4)
                && (requestMessage.Command == Rpc.Commands.Neighbor.GetNr()))
            {
                throw new ArgumentException("Message content is wrong for this handler.");
            }

            Number160 locationKey = requestMessage.Key(0);
            Number160 domainKey = requestMessage.Key(1);

            var neighbors = GetNeighbors(locationKey, NeighborSize);
            if (neighbors == null)
            {
                // return empty neighbor set
                var response = CreateResponseMessage(requestMessage, Message.Message.MessageType.NotFound);
                response.SetNeighborSet(new NeighborSet(-1, new Collection<PeerAddress>()));
                responder.Response(response);
                return;
            }

            // create response message and set neighbors
            var responseMessage = CreateResponseMessage(requestMessage, Message.Message.MessageType.Ok);

            Logger.Debug("Found the following neighbors: {0}.", Convenient.ToString(neighbors));
            var neighborSet = new NeighborSet(NeighborLimit, neighbors);
            responseMessage.SetNeighborSet(neighborSet);

            Number160 contentKey = requestMessage.Key(2);
            var keyBloomFilter = requestMessage.BloomFilter(0);
            var contentBloomFilter = requestMessage.BloomFilter(1);
            var keyCollection = requestMessage.KeyCollection(0);

            // it is important to set an integer if a value is present
            bool isDigest = requestMessage.Type != Message.Message.MessageType.Request1;
            if (isDigest)
            {
                if (requestMessage.Type == Message.Message.MessageType.Request2)
                {
                    DigestInfo digestInfo;
                    if (PeerBean.DigestStorage == null)
                    {
                        // no storage to search
                        digestInfo = new DigestInfo();
                    }
                    else if (contentKey != null && locationKey != null && domainKey != null)
                    {
                        var locationAndDomainKey = new Number320(locationKey, domainKey);
                        var from = new Number640(locationAndDomainKey, contentKey, Number160.Zero);
                        var to = new Number640(locationAndDomainKey, contentKey, Number160.MaxValue);
                        digestInfo = PeerBean.DigestStorage.Digest(from, to, -1, true);
                    }
                    else if ((keyBloomFilter != null || contentBloomFilter != null) && locationKey != null && domainKey != null)
                    {
                        var locationAndDomainKey = new Number320(locationKey, domainKey);
                        digestInfo = PeerBean.DigestStorage.Digest(locationAndDomainKey, keyBloomFilter,
                                contentBloomFilter, -1, true, true);
                    }
                    else if (keyCollection != null && keyCollection.Keys.Count == 2)
                    {
                        var enumerator = keyCollection.Keys.GetEnumerator();
                        var from = enumerator.MoveNext() ? enumerator.Current : null; // TODO works correctly?
                        var to = enumerator.MoveNext() ? enumerator.Current : null;

                        digestInfo = PeerBean.DigestStorage.Digest(from, to, -1, true);
                    }
                    else if (locationKey != null && domainKey != null)
                    {
                        var locationAndDomainKey = new Number320(locationKey, domainKey);
                        var from = new Number640(locationAndDomainKey, Number160.Zero, Number160.Zero);
                        var to = new Number640(locationAndDomainKey, Number160.MaxValue, Number160.MaxValue);
                        digestInfo = PeerBean.DigestStorage.Digest(from, to, -1, true);
                    }
                    else
                    {
                        Logger.Warn("Did not search for anything.");
                        digestInfo = new DigestInfo();
                    }
                    responseMessage.SetIntValue(digestInfo.Size);
                    responseMessage.SetKey(digestInfo.KeyDigest);
                    responseMessage.SetKey(digestInfo.ContentDigest);
                }
                else if (requestMessage.Type == Message.Message.MessageType.Request3)
                {
                    DigestInfo digestInfo;
                    if (PeerBean.DigestTracker == null)
                    {
                        // no tracker to search
                        digestInfo = new DigestInfo();
                    }
                    else
                    {
                        digestInfo = PeerBean.DigestTracker.Digest(locationKey, domainKey, contentKey);
                        if (digestInfo.Size == 0)
                        {
                            Logger.Debug("No entry found on peer {0}.", requestMessage.Recipient);
                        }
                    }
                    responseMessage.SetIntValue(digestInfo.Size);
                }
                else if (requestMessage.Type == Message.Message.MessageType.Request4)
                {
                    lock (PeerBean.PeerStatusListeners)
                    {
                        foreach (var listener in PeerBean.PeerStatusListeners)
                        {
                            listener.PeerFailed(requestMessage.Sender,
                                new PeerException(PeerException.AbortCauseEnum.Shutdown, "shutdown"));
                        }
                    }
                }
            }

            responder.Response(responseMessage);
        }