Пример #1
0
/**
 * \brief Read string field
 */
void Storage::readString(uint16_t& length, uint8_t *data_record, uint16_t &offset)
{
	/* Get string length */
	length = realLength(length, data_record, offset);
	
	/* Read string */
	record.append((const char *)(data_record + offset), length);
}
Пример #2
0
/**
 * \brief Store data record
 */
void Storage::storeDataRecord(struct metadata *mdata, struct json_conf * config)
{
	const char *element_name = NULL;
	ELEMENT_TYPE element_type;

	offset = 0;
	uint16_t trans_len = 0;
	const char *trans_str = NULL;
	record.clear();
	STR_APPEND(record, "{\"@type\": \"ipfix.entry\", ");

	struct ipfix_template *templ = mdata->record.templ;
	uint8_t *data_record = (uint8_t*) mdata->record.record;

	/* get all fields */
	uint16_t added = 0;
	for (uint16_t count = 0, index = 0; count < templ->field_count; ++count, ++index) {
		/* Get Enterprise number and ID */
		id = templ->fields[index].ie.id;
		length = templ->fields[index].ie.length;
		enterprise = 0;
		
		if (id & 0x8000) {
			id &= 0x7fff;
			enterprise = templ->fields[++index].enterprise_number;
		}
		
		/* Get element informations */
		const ipfix_element_t * element = get_element_by_id(id, enterprise);
		if (element != NULL) {
			element_name = element->name;
			element_type = element->type;
		} else {
			// Element not found
			if (config->ignoreUnknown) {
				offset += realLength(length, data_record, offset);
				continue;
			}

			element_name = rawName(enterprise, id);
			element_type = ET_UNASSIGNED;
			MSG_DEBUG(msg_module, "Unknown element (%s)", element_name);
	}

		if (added > 0) {
			STR_APPEND(record, ", ");
		}

		STR_APPEND(record, "\"");
		record += config->prefix;
		record += element_name;
		STR_APPEND(record, "\": ");

		switch (element_type) {
		case ET_UNSIGNED_8:
		case ET_UNSIGNED_16:
		case ET_UNSIGNED_32:
		case ET_UNSIGNED_64:{
			trans_str = translator.toUnsigned(length, &trans_len, data_record, offset,
				element, config);
			record.append(trans_str, trans_len);
		}
			break;
		case ET_SIGNED_8:
		case ET_SIGNED_16:
		case ET_SIGNED_32:
		case ET_SIGNED_64:
			trans_str = translator.toSigned(length, &trans_len, data_record, offset);
			record.append(trans_str, trans_len);
			break;
		case ET_FLOAT_32:
		case ET_FLOAT_64:
			trans_str = translator.toFloat(length, &trans_len, data_record, offset);
			record.append(trans_str, trans_len);
			break;
		case ET_IPV4_ADDRESS:
			record += '"';
			trans_str = translator.formatIPv4(read32(data_record + offset), &trans_len);
			record.append(trans_str, trans_len);
			record += '"';
			break;
		case ET_IPV6_ADDRESS:
			READ_BYTE_ARR(addr6, data_record + offset, IPV6_LEN);
			record += '"';
			record += translator.formatIPv6(addr6);
			record += '"';
			break;
		case ET_MAC_ADDRESS:
			READ_BYTE_ARR(addrMac, data_record + offset, MAC_LEN);
			record += '"';
			record += translator.formatMac(addrMac);
			record += '"';
			break;
		case ET_DATE_TIME_SECONDS:
			record += translator.formatTimestamp(read32(data_record + offset),
				t_units::SEC, config);
			break;
		case ET_DATE_TIME_MILLISECONDS:
			record += translator.formatTimestamp(read64(data_record + offset),
				t_units::MILLISEC, config);
			break;
		case ET_DATE_TIME_MICROSECONDS:
			record += translator.formatTimestamp(read64(data_record + offset),
				t_units::MICROSEC, config);
			break;
		case ET_DATE_TIME_NANOSECONDS:
			record += translator.formatTimestamp(read64(data_record + offset),
				t_units::NANOSEC, config);
			break;
		case ET_STRING:
			length = realLength(length, data_record, offset);
			record += translator.escapeString(length, data_record + offset,
				config);
			break;
		case ET_BOOLEAN:
		case ET_UNASSIGNED: 
		default:
			readRawData(length, data_record, offset);
			break;
		}

		offset += length;
		added++;
	}
	
	/* Store metadata */
	if (processMetadata) {
		STR_APPEND(record, ", \"ipfix.metadata\": {");
		storeMetadata(mdata);
		STR_APPEND(record, "}");
	}
	
	STR_APPEND(record, "}\n");
	sendData();
}
Пример #3
0
void Trace::slowCompressLoop(int window){
  static int warned_once = 0;
  int distance;
  Event *iter;
  iteration_t *rtn;
  iteration_t *iteration;
  vector<iteration_t *> iterations;
  vector<iteration_t *>::iterator iteration_it;
  int i;

  int head_flag;      /* Whether target head has been found. */
  int match_flag;     /* Whether a node matching target head has been found. */
  int found_flag;     /* */

  int target_length=1, merge_length=1;
  int target_real_length, merge_real_length;
  double ratio;

  Event *target_tail = NULL;
  Event *target_head = NULL;
  Event *merge_tail = NULL;
  Event *merge_head = NULL;

#if defined FEATURE_SIG_DIFF && FEATURE_SIG_DIFF > 0
  Event* search;
  StackSig* target_sig;
  StackSig* merge_sig;
#endif

  distance = 0;
  head_flag = 0;
  found_flag = 1;

  do {
    target_tail = tail;

    if(found_flag || !head_flag) {
      /* if the found flag is set - start a new search */
      target_head = target_tail;
      distance = 0;
      target_length = merge_length = 1;
    } else {
      /* otherwise continue a previous search */
      target_head = target_head->prev;
      target_length++;
      merge_length = 1;
    }

    head_flag = 0;
    match_flag = 0;
    found_flag = 0;


    /* Search backwards in the queue until we find a match with the target tail.
     * After this loop is done, either head_flag will be false (and nothing found)
     * or the head will be just after the matching tail. */
    while(target_head->prev != NULL && (window == -1 || window > distance)) {
      if( !target_head->checkLoc(MEMBER)
          && !target_head->checkLoc(PENDING_MEMBER)
          && !target_head->checkLoc(PENDING_LEADER)
          && !target_head->checkLoc(PENDING_TAIL)
          && target_tail->sigMatch(target_head->prev)
          && target_tail->opMatch(target_head->prev)){
        head_flag = 1;
        break;
      }
      target_head = target_head->prev;
      target_length++;
      distance++;
    }

    /* didn't find head: can skip the rest. */
    if (!head_flag) {
      /* Warn if the window was exceeded, but only warn once. */
      if(!warned_once && window != -1 && window <= distance) {
        cerr<<"warning: window exceeded - possible compression missed (window: "<<window<<"   distance: "<<distance<<")"<<endl;
        warned_once = 1;
      }
      break;
    }

    /* If the head flag is true, we've got the target_tail, the target_head, and
     * the merge_tail (just before target_head). Now we can try to find a match
     * for the target_head somewhere before the merge tail.  This will be merge_head.*/
    merge_head = target_head->prev;
    merge_tail = target_head->prev;

    while(merge_head != NULL) {
      if( !merge_head->checkLoc(MEMBER)
          && merge_head->sigMatch(target_head)
          && merge_head->opMatch(target_head)){

        target_real_length = realLength(target_head, target_tail);
        merge_real_length = realLength(merge_head, merge_tail);
        assert(target_real_length > 0 && merge_real_length > 0);
        if(target_real_length > merge_real_length){
          ratio = (double)merge_real_length / (double)target_real_length;
        } else {
          ratio = (double)target_real_length / (double)merge_real_length;
        }
        if(1 - ratio < MAX_LENGTH_DIFF){
#if defined FEATURE_SIG_DIFF && FEATURE_SIG_DIFF > 0
          /* heuristic that helps to identify the best match */
          if( (target_tail->sigEquals(merge_tail) && target_head->sigEquals(merge_head))
              || (merge_length == target_length && merge_length == 1 )  )
#endif
            if(merge_head->checkLoc(PENDING_MEMBER) || merge_head->checkLoc(PENDING_LEADER)
                || merge_head->checkLoc(PENDING_TAIL)){
              for(iter = merge_head, i = 0; iter; iter = iter->prev, i++){
                iterations = pendingIterations.getIterationsByTargetHead(iter);
                if(iterations.size() == 1){
                  if(iterations[0]->target_tail->getId() >= merge_head->getId()){
                    break;
                  }
                }else{
                  /* only one pending iteration can have iter as the
                   * target_head, because it's impossible to choose a
                   * PENDING_LEADER event as the target_head */
                  assert(iterations.size()==0);
                }
                iterations.clear();
              }
              if(iterations.size() == 1 && (merge_tail == iterations[0]->target_tail)){
                match_flag = 1;
                break;
              }
            } else {
              match_flag = 1;
              break;
            }
        }
      }
      merge_head = merge_head->prev;
      merge_length++;
    }

    /* If we didn't find the merge head, we continue to the next iteration to try to
     * find a longer iteration. */
    if(!match_flag)
      continue;
    found_flag = 1;

    /* mark the loop iteration */
    /* 1. check if the current iteration is a trailing iteration, if
     * it is a trailing iteration, only the case where merge_tail equals
     * to the tail of the pervious iteration is allowed */
    if(merge_head->checkLoc(PENDING_MEMBER) || merge_head->checkLoc(PENDING_LEADER)
        || merge_head->checkLoc(PENDING_TAIL)){
      for(iter = merge_head, i = 0; iter; iter = iter->prev, i++){
        iterations = pendingIterations.getIterationsByTargetHead(iter);
        if(iterations.size() == 1){
          //if(iterations[0]->target_length - i > 0){
          if(iterations[0]->target_tail->getId() >= merge_head->getId()){
            break;
          }
        }else{
          /* only one pending iteration can have iter as the
           * target_head, because it's impossible to choose a
           * PENDING_LEADER event as the target_head */
          assert(iterations.size()==0);
        }
        iterations.clear();
      }

      if(iterations.size() == 1 && (merge_tail == iterations[0]->target_tail)){
        iterations = pendingIterations.getIterationsByTargetTail(merge_tail);
        for(iteration_it = iterations.begin();
            iteration_it != iterations.end(); iteration_it++)
          for(iter = (*iteration_it)->target_tail;
              iter != (*iteration_it)->target_head; iter = iter->prev)
            if(iter == merge_head){
              (*iteration_it)->target_tail->unsetLoc(PENDING_TAIL);
              (*iteration_it)->target_tail->setLoc(PENDING_MEMBER);
              pendingIterations.updateIterationTargetTail((*iteration_it), target_tail);
              (*iteration_it)->target_length += target_length;
              break;
            }

      } else {
        found_flag = 0;
        continue;
      }
    }


#if defined FEATURE_SIG_DIFF && FEATURE_SIG_DIFF > 0
    if(!target_tail->sigEquals(merge_tail)){
      target_sig = target_tail->getSignature();
      merge_sig = merge_tail->getSignature();
      search = target_tail;
      while(search != merge_tail){
        search->updateStatsSig(target_sig, merge_sig);
        search = search->prev;
      }
      target_tail->setSignature(*merge_sig);
    }
    if(target_tail != target_head && !target_head->sigEquals(merge_head)){
      target_sig = target_head->getSignature();
      merge_sig = merge_head->getSignature();
      search = target_tail;
      while(search != merge_tail){
        search->updateStatsSig(target_sig, merge_sig);
        search = search->prev;
      }
      target_head->setSignature(*merge_sig);
    }
#endif


    /* 2. if merge_head ... merge_tail is a pending iteration, merge it */
    iterations = pendingIterations.getIterationsByTargetHead(merge_head);
    rtn = NULL;
    for(iteration_it = iterations.begin(); iteration_it != iterations.end(); iteration_it++){
      if((*iteration_it)->target_head == merge_head && (*iteration_it)->target_tail == merge_tail){
        iteration = *iteration_it;
        rtn = compressLoopLCS(iteration);
        updateIds(rtn->merge_head);
        break;
      }
    }

    /* 3. mark the current iteration as pending */
    if(rtn){
      pendingIterations.create(rtn->merge_head, rtn->merge_tail, rtn->merge_length,
          target_head, target_tail, target_length);
      delete rtn;
    } else {
      pendingIterations.create(merge_head, merge_tail, merge_length, target_head, target_tail, target_length);
      for(iter = merge_tail; iter != merge_head && iter != NULL; iter=iter->prev)
        iter->setLoc(MEMBER);
      assert(iter);
      iter->setLoc(LEADER);
    }
    /* mark the events in the target iteration as PENDING */
    target_tail->setLoc(PENDING_TAIL);
    if(target_tail != target_head){
      for(iter = target_tail->prev; iter != target_head && iter != NULL; iter = iter->prev)
        iter->setLoc(PENDING_MEMBER);
    }
    target_head->setLoc(PENDING_LEADER);

  } while(head_flag && !found_flag);

} /* slowCompressLoop */