Exemplo n.º 1
0
        private IoBuffer InsertBytesToNewIoBuffer(IoSession session, IoBuffer buffer)
        {
            if (_insertByteProbability > _rng.Next(1000))
            {
                if (log.IsInfoEnabled)
                {
                    log.Info(buffer.GetHexDump());
                }

                // where to insert bytes ?
                int pos = _rng.Next(buffer.Remaining) - 1;

                // how many byte to insert ?
                int count = _rng.Next(_maxInsertByte - 1) + 1;

                IoBuffer newBuff = IoBuffer.Allocate(buffer.Remaining + count);
                for (int i = 0; i < pos; i++)
                {
                    newBuff.Put(buffer.Get());
                }
                for (int i = 0; i < count; i++)
                {
                    newBuff.Put((byte)(_rng.Next(256)));
                }
                while (buffer.Remaining > 0)
                {
                    newBuff.Put(buffer.Get());
                }
                newBuff.Flip();

                if (log.IsInfoEnabled)
                {
                    log.Info("Inserted " + count + " bytes.");
                    log.Info(newBuff.GetHexDump());
                }
                return(newBuff);
            }
            return(null);
        }
Exemplo n.º 2
0
        private void ManipulateIoBuffer(IoSession session, IoBuffer buffer)
        {
            if ((buffer.Remaining > 0) && (_removeByteProbability > _rng.Next(1000)))
            {
                if (log.IsInfoEnabled)
                {
                    log.Info(buffer.GetHexDump());
                }

                // where to remove bytes ?
                int pos = _rng.Next(buffer.Remaining);
                // how many byte to remove ?
                int count = _rng.Next(buffer.Remaining - pos) + 1;
                if (count == buffer.Remaining)
                {
                    count = buffer.Remaining - 1;
                }

                IoBuffer newBuff = IoBuffer.Allocate(buffer.Remaining - count);
                for (int i = 0; i < pos; i++)
                {
                    newBuff.Put(buffer.Get());
                }

                buffer.Skip(count); // hole
                while (newBuff.Remaining > 0)
                {
                    newBuff.Put(buffer.Get());
                }
                newBuff.Flip();
                // copy the new buffer in the old one
                buffer.Rewind();
                buffer.Put(newBuff);
                buffer.Flip();

                if (log.IsInfoEnabled)
                {
                    log.Info("Removed " + count + " bytes at position " + pos + ".");
                    log.Info(buffer.GetHexDump());
                }
            }
            if ((buffer.Remaining > 0) && (_changeByteProbability > _rng.Next(1000)))
            {
                if (log.IsInfoEnabled)
                {
                    log.Info(buffer.GetHexDump());
                }

                // how many byte to change ?
                int count = _rng.Next(buffer.Remaining - 1) + 1;

                byte[] values = new byte[count];
                _rng.NextBytes(values);
                for (int i = 0; i < values.Length; i++)
                {
                    int pos = _rng.Next(buffer.Remaining);
                    buffer.Put(pos, values[i]);
                }

                if (log.IsInfoEnabled)
                {
                    log.Info("Modified " + count + " bytes.");
                    log.Info(buffer.GetHexDump());
                }
            }
        }
Exemplo n.º 3
0
        /// <inheritdoc/>
        public override void MessageReceived(INextFilter nextFilter, IoSession session, Object message)
        {
            //if (log.IsDebugEnabled)
            //    log.DebugFormat("Processing a MESSAGE_RECEIVED for session {0}", session.Id);

            IoBuffer input = message as IoBuffer;

            if (input == null)
            {
                nextFilter.MessageReceived(session, message);
                return;
            }

            IProtocolDecoder       decoder       = _factory.GetDecoder(session);
            IProtocolDecoderOutput decoderOutput = GetDecoderOut(session, nextFilter);

            // Loop until we don't have anymore byte in the buffer,
            // or until the decoder throws an unrecoverable exception or
            // can't decoder a message, because there are not enough
            // data in the buffer
            while (input.HasRemaining)
            {
                Int32 oldPos = input.Position;
                try
                {
                    // TODO may not need lock on UDP
                    lock (session)
                    {
                        // Call the decoder with the read bytes
                        decoder.Decode(session, input, decoderOutput);
                    }

                    // Finish decoding if no exception was thrown.
                    decoderOutput.Flush(nextFilter, session);
                }
                catch (Exception ex)
                {
                    ProtocolDecoderException pde = ex as ProtocolDecoderException;
                    if (pde == null)
                    {
                        pde = new ProtocolDecoderException(null, ex);
                    }
                    if (pde.Hexdump == null)
                    {
                        // Generate a message hex dump
                        Int32 curPos = input.Position;
                        input.Position = oldPos;
                        pde.Hexdump    = input.GetHexDump();
                        input.Position = curPos;
                    }

                    decoderOutput.Flush(nextFilter, session);
                    nextFilter.ExceptionCaught(session, pde);

                    // Retry only if the type of the caught exception is
                    // recoverable and the buffer position has changed.
                    // We check buffer position additionally to prevent an
                    // infinite loop.
                    if (!(ex is RecoverableProtocolDecoderException) || input.Position == oldPos)
                    {
                        break;
                    }
                }
            }
        }
Exemplo n.º 4
0
        /// <inheritdoc/>
        protected override bool DoDecode(IoSession session, IoBuffer input, IProtocolDecoderOutput output)
        {
            State state = GetState(session);

            if (state.currentDecoder == null)
            {
                IMessageDecoder[] decoders = state.decoders;
                int undecodables           = 0;

                for (int i = decoders.Length - 1; i >= 0; i--)
                {
                    IMessageDecoder decoder = decoders[i];
                    int             limit   = input.Limit;
                    int             pos     = input.Position;

                    MessageDecoderResult result;

                    try
                    {
                        result = decoder.Decodable(session, input);
                    }
                    finally
                    {
                        input.Position = pos;
                        input.Limit    = limit;
                    }

                    if (result == MessageDecoderResult.OK)
                    {
                        state.currentDecoder = decoder;
                        break;
                    }
                    else if (result == MessageDecoderResult.NotOK)
                    {
                        undecodables++;
                    }
                    else if (result != MessageDecoderResult.NeedData)
                    {
                        throw new InvalidOperationException("Unexpected decode result (see your decodable()): " + result);
                    }
                }

                if (undecodables == decoders.Length)
                {
                    // Throw an exception if all decoders cannot decode data.
                    String dump = input.GetHexDump();
                    input.Position = input.Limit; // Skip data

                    //seem to be a bug not remove session buffer
                    //add code to remove session buffer.
                    RemoveSessionBuffer(session);

                    ProtocolDecoderException e = new ProtocolDecoderException("No appropriate message decoder: " + dump);
                    e.Hexdump = dump;
                    throw e;
                }

                if (state.currentDecoder == null)
                {
                    // Decoder is not determined yet (i.e. we need more data)
                    return(false);
                }
            }

            try
            {
                MessageDecoderResult result = state.currentDecoder.Decode(session, input, output);
                if (result == MessageDecoderResult.OK)
                {
                    state.currentDecoder = null;
                    return(true);
                }
                else if (result == MessageDecoderResult.NeedData)
                {
                    return(false);
                }
                else if (result == MessageDecoderResult.NotOK)
                {
                    state.currentDecoder = null;
                    throw new ProtocolDecoderException("Message decoder returned NOT_OK.");
                }
                else
                {
                    state.currentDecoder = null;
                    throw new InvalidOperationException("Unexpected decode result (see your decode()): " + result);
                }
            }
            catch (Exception)
            {
                state.currentDecoder = null;
                throw;
            }
        }