@Override
    protected int onReadPacketHeader( ByteBuffer in )
    {
        if (in.remaining() < HEADER_SIZE)
        {
            return ON_READ_REWIND;
        }
        
        int magicNumber = in.getInt();
        
        if (magicNumber != protocol.getMagicNumber())
        {
            return ON_READ_CLOSE;
        }

        long packetTime = in.getLong();
        long receivedTime = in.getLong();
        int ack = in.getInt(); // this is the packet index the other last received
        int ackSequence = in.getInt(); // this is the bitset of previous packets they received
        int packetSize = in.getInt();
        
        if (in.remaining() < packetSize)
        {
            return ON_READ_REWIND;
        }
        
        pingTime = System.nanoTime() - receivedTime;
        lastReceivedPacketSize = packetSize;
        lastReceivedPacketTime = packetTime;
        readAck = ack;
        readAckSequence = ackSequence;
        
        // use ack and acksequence to remove any pending calls
        // if ack is a jump from the last packet index sent, add the calls in between to out-bound
        // if packetIndex is one we already received, jump to end of packet and ignore all calls
        // if packetIndex is one we were missing, check for complete call sequences for ordered channels

        return packetSize;
    }