def _data_received(self, next_bytes):
        """Maintains buffer of bytes received from peer and extracts bgp
        message from this buffer if enough data is received.

        Validates bgp message marker, length, type and data and constructs
        appropriate bgp message instance and calls handler.

        :Parameters:
            - `next_bytes`: next set of bytes received from peer.
        """
        # Append buffer with received bytes.
        self._recv_buff += next_bytes

        while True:
            # If current buffer size is less then minimum bgp message size, we
            # return as we do not have a complete bgp message to work with.
            if len(self._recv_buff) < BGP_MIN_MSG_LEN:
                return

            # Parse message header into elements.
            auth, length, ptype = BgpProtocol.parse_msg_header(
                self._recv_buff[:BGP_MIN_MSG_LEN])

            # Check if we have valid bgp message marker.
            # We should get default marker since we are not supporting any
            # authentication.
            if (auth != BgpProtocol.MESSAGE_MARKER):
                LOG.error('Invalid message marker received: %s', auth)
                raise bgp.NotSync()

            # Check if we have valid bgp message length.
            check = (length < BGP_MIN_MSG_LEN or length > BGP_MAX_MSG_LEN)

            # RFC says: The minimum length of the OPEN message is 29
            # octets (including the message header).
            check2 = (ptype == BGP_MSG_OPEN and length < BGPOpen._MIN_LEN)

            # RFC says: A KEEPALIVE message consists of only the
            # message header and has a length of 19 octets.
            check3 = (ptype == BGP_MSG_KEEPALIVE and
                      length != BGPKeepAlive._MIN_LEN)

            # RFC says: The minimum length of the UPDATE message is 23
            # octets.
            check4 = (ptype == BGP_MSG_UPDATE and
                      length < BGPUpdate._MIN_LEN)

            if any((check, check2, check3, check4)):
                raise bgp.BadLen(ptype, length)

            # If we have partial message we wait for rest of the message.
            if len(self._recv_buff) < length:
                return
            msg, _, rest = BGPMessage.parser(self._recv_buff)
            self._recv_buff = rest

            # If we have a valid bgp message we call message handler.
            self._handle_msg(msg)