Channel buffer not valid after disconnect event

83 views
Skip to first unread message

Yogesh Vedpathak

unread,
Dec 6, 2012, 10:31:33 AM12/6/12
to ne...@googlegroups.com
I am getting channel closed event first and then I receive exceptionCaught event. There is runtime exception (ArrayIndexOutOfBounds) caused in the channel decoder while reading from buffer. Should my decoder code make sure that channel is connected (or buffer) is valid every time it tries to read? 

Regards,
Yogesh Vedpathak

Norman Maurer

unread,
Dec 11, 2012, 11:43:14 AM12/11/12
to ne...@googlegroups.com
Can you include the stack trace ?
---
Norman Maurer


Yogesh Vedpathak

unread,
Dec 11, 2012, 12:15:57 PM12/11/12
to ne...@googlegroups.com
Here are the stack traces. Also notice the timestamps. 

---exceptionCause event in handler 
2012-10-17 13:37:20.116 WARN  [New I/O server worker #1-95] org.cleversafe.protocol.acceptor.netty.NettyAcceptorHandler - Network exception occurred [/172.16.18.155:56763]: Connection reset by peer
java.io.IOException: Connection reset by peer
        at sun.nio.ch.FileDispatcher.read0(Native Method)
        at sun.nio.ch.SocketDispatcher.read(Unknown Source)
        at sun.nio.ch.IOUtil.readIntoNativeBuffer(Unknown Source)
        at sun.nio.ch.IOUtil.read(Unknown Source)
        at sun.nio.ch.SocketChannelImpl.read(Unknown Source)
        at org.jboss.netty.channel.socket.nio.NioWorker.read(NioWorker.java:321)
        at org.jboss.netty.channel.socket.nio.NioWorker.processSelectedKeys(NioWorker.java:280)
        at org.jboss.netty.channel.socket.nio.NioWorker.run(NioWorker.java:200)
        at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
        at java.lang.Thread.run(Unknown Source)

---exception in the decoder
2012-10-17 13:37:20.162 WARN  [New I/O server worker #1-95] org.cleversafe.protocol.acceptor.netty.NettyAcceptorHandler - Network exception occurred [/172.16.18.155:56763]: -1999213646
java.lang.ArrayIndexOutOfBoundsException: -1999213646
        at org.jboss.netty.buffer.HeapChannelBuffer.getByte(HeapChannelBuffer.java:95)
        at org.jboss.netty.buffer.AbstractChannelBuffer.readByte(AbstractChannelBuffer.java:238)
        at org.jboss.netty.buffer.ChannelBufferInputStream.readByte(ChannelBufferInputStream.java:149)
        at org.jboss.netty.buffer.ChannelBufferInputStream.readUnsignedByte(ChannelBufferInputStream.java:213)
        at org.cleversafe.protocol.impl.GridProtocolHeaderCodec.<init>(GridProtocolHeaderCodec.java:108)
        at org.cleversafe.protocol.acceptor.netty.MessageDecoder.decode(MessageDecoder.java:73)
        at org.jboss.netty.handler.codec.frame.FrameDecoder.callDecode(FrameDecoder.java:282)
        at org.jboss.netty.handler.codec.frame.FrameDecoder.messageReceived(FrameDecoder.java:216)
        at org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:274)
        at org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:261)
        at org.jboss.netty.channel.socket.nio.NioWorker.read(NioWorker.java:349)
        at org.jboss.netty.channel.socket.nio.NioWorker.processSelectedKeys(NioWorker.java:280)
        at org.jboss.netty.channel.socket.nio.NioWorker.run(NioWorker.java:200)
        at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
        at java.lang.Thread.run(Unknown Source)



Norman Maurer

unread,
Dec 11, 2012, 12:16:58 PM12/11/12
to ne...@googlegroups.com
Can I also see the "org.cleversafe.protocol.impl.GridProtocolHeaderCodec" class ?
---
Norman Maurer



Am 11.12.2012 um 18:15 schrieb Yogesh Vedpathak <yvedp...@cleversafe.com>:

org.cleversafe.protocol.impl.GridProtocolHeaderCodec

Yogesh Vedpathak

unread,
Dec 11, 2012, 12:36:04 PM12/11/12
to ne...@googlegroups.com
I pasted it here. So do you think this is because I am wrapping it in data stream? 

 /**
    * Constructor. Takes the byte array and deserializes it into a Header object.
    * 
    * @param header
    *           The header byte array.
    * @throws HeaderFormatException
    */
   public GridProtocolHeaderCodec(final byte[] header) throws HeaderFormatException
   {
      this(new DataInputStream(new ByteArrayInputStream(header)));
   }


   /**
    * Constructor. Takes the byte array and deserializes it into a Header object.
    * 
    * @param header
    *           The header byte array.
    * @throws HeaderFormatException
    */
 public GridProtocolHeaderCodec(final DataInput in) throws HeaderFormatException
   {
     // Read from input
      final int protocolClass;
      final int protocolVersion;
      try
      {
         protocolClass = in.readUnsignedByte();
         protocolVersion = in.readUnsignedByte();
         this.operationCode = (byte) in.readUnsignedByte();
         this.isResponse = (in.readUnsignedByte() & 0x80) != 0;
         this.sequenceNumber = in.readInt();
         this.payloadLength = in.readInt();

         // Todo: make it configurable, see DE2735
         if (this.payloadLength > MAX_PAYLOAD_SIZE)
         {
            final String message =
                  "Payload size exceeds max allowed " + this.payloadLength + " > "
                        + MAX_PAYLOAD_SIZE;
            dumpHeader(protocolClass, protocolVersion);
            throw new HeaderFormatException(message);
         }
      }
      catch (final EOFException eof)
      {
         throw new HeaderFormatException("Incomplete header", eof);
      }
      catch (final IOException ioe)
      {
         throw new HeaderFormatException(
               "Header bytes passed in constructor are of invalid format!", ioe);
      }
   }
Regards,
Yogesh Vedpathak

From: Norman Maurer <nma...@redhat.com>
Reply-To: "ne...@googlegroups.com" <ne...@googlegroups.com>
Date: Tue, 11 Dec 2012 11:16:58 -0600
To: "ne...@googlegroups.com" <ne...@googlegroups.com>
Subject: Re: Channel buffer not valid after disconnect event

Norman Maurer

unread,
Dec 11, 2012, 1:08:02 PM12/11/12
to ne...@googlegroups.com
Please include the "whole" class..


---
Norman Maurer


Yogesh Vedpathak

unread,
Dec 11, 2012, 2:44:03 PM12/11/12
to ne...@googlegroups.com
Here it is. 

public class GridProtocolHeaderCodec
{
   private static final Logger _logger = LoggerFactory.getLogger(GridProtocolHeaderCodec.class);

   private int sequenceNumber;
   private byte operationCode;
   private boolean isResponse;
   private int payloadLength;

   public static final int LENGTH = 12;
   public static final byte PROTOCOL_CLASS = 1;
   public static final byte PROTOCOL_VERSION = 1;

   private static final int MAX_PAYLOAD_SIZE = (int) (100 * Size.MiB);

   /**
    * Constructor. Takes the deserialized integer values and creates the Header object.
    * 
    * @param sequenceNumber
    * @param operationCode
    * @param payloadLength
    */
   public GridProtocolHeaderCodec(
         final int sequenceNumber,
         final byte operationCode,
         final boolean isResponse,
         final int payloadLength)
   {
      this.sequenceNumber = sequenceNumber;
      this.operationCode = operationCode;
      this.payloadLength = payloadLength;
      this.isResponse = isResponse;
   }

   /**
    * Constructor. Takes the byte array and deserializes it into a Header object.
    * 
    * @param header
    *           The header byte array.
    * @throws HeaderFormatException
    */
   public GridProtocolHeaderCodec(final byte[] header) throws HeaderFormatException
   {
      this(new DataInputStream(new ByteArrayInputStream(header)));
   }

   public static GridProtocolHeaderCodec create(final ByteBuffer header)
         throws HeaderFormatException
   {
      final byte[] bytes = new byte[LENGTH];
      header.get(bytes);
      return new GridProtocolHeaderCodec(new DataInputStream(new ByteArrayInputStream(bytes)));
   }

   /**
    * Constructor. Takes the byte array and deserializes it into a Header object.
    * 
    * @param header
    *           The header byte array.
    * @throws HeaderFormatException
    */
   public GridProtocolHeaderCodec(final DataInput in) throws HeaderFormatException
   {
      // Read from input
      final int protocolClass;
      final int protocolVersion;
      try
      {
         protocolClass = in.readUnsignedByte();
         protocolVersion = in.readUnsignedByte();
         this.operationCode = (byte) in.readUnsignedByte();
         this.isResponse = (in.readUnsignedByte() & 0x80) != 0;
         this.sequenceNumber = in.readInt();
         this.payloadLength = in.readInt();

         // Todo: make it configurable, see DE2735
         if (this.payloadLength > MAX_PAYLOAD_SIZE)
         {
            final String message =
                  "Payload size exceeds max allowed " + this.payloadLength + " > "
                        + MAX_PAYLOAD_SIZE;
            dumpHeader(protocolClass, protocolVersion);
            throw new HeaderFormatException(message);
         }
      }
      catch (final EOFException eof)
      {
         throw new HeaderFormatException("Incomplete header", eof);
      }
      catch (final IOException ioe)
      {
         throw new HeaderFormatException(
               "Header bytes passed in constructor are of invalid format!", ioe);
      }
   }

   private void dumpHeader(final int protocolClass, final int protocolVersion)
   {
      final StringBuffer header = new StringBuffer("Invalid packet - Packet dump");
      header.append("\nclass: ").append(protocolClass);
      header.append("\nopCode: ").append(this.operationCode);
      header.append("\nisResponse: ").append(this.isResponse);
      header.append("\nsequence: ").append(this.sequenceNumber);
      header.append("\npayloadLen: ").append(this.payloadLength);
      _logger.warn(header.toString());
   }

   public void serialize(final ByteBuffer buffer)
   {
      write(buffer);
   }

   /**
    * Writes the header to the speicified output stream
    */
   public void write(final ByteBuffer byteBuffer)
   {
      _logger.trace("Serializing a Header object into a header byte array.");

      byteBuffer.put(PROTOCOL_CLASS);
      byteBuffer.put(PROTOCOL_VERSION);
      byteBuffer.put(this.operationCode);
      byteBuffer.put(this.isResponse ? (byte) 0x80 : (byte) 0x00);
      byteBuffer.putInt(this.sequenceNumber);
      byteBuffer.putInt(this.payloadLength);
   }

   /**
    * Returns the sequence number.
    * 
    * @return The sequence number.
    */
   public int getSequenceNumber()
   {
      return this.sequenceNumber;
   }

   /**
    * Returns the payload length.
    * 
    * @return The payload length.
    */
   public int getPayloadLength()
   {
      return this.payloadLength;
   }

   /**
    * Returns the protocol operation code.
    * 
    * @return The protocol operation code.
    */
   public int getOperationCode()
   {
      return this.operationCode;
   }

   @Override
   public String toString()
   {
      return "Protocol Header [ID=" + this.sequenceNumber + " C=" + this.operationCode + " L="
            + this.payloadLength + "]";
   }

   public boolean isResponse()
   {
      return this.isResponse;
   }
}
Regards,
Yogesh Vedpathak

Trustin Lee

unread,
Dec 11, 2012, 10:37:05 PM12/11/12
to ne...@googlegroups.com

To me, it just looks like your codec made an assumption that your buffer has a complete message which is not always true. Can you confirm?

Reply all
Reply to author
Forward
0 new messages