Beispiel #1
0
/**
 * \brief Change mode of output manager
 *
 * Allow to change mode from single mode to multi mode and vice versa.
 * If new mode is different from current mode, all data managers are removed.
 * If the manager thread is running, it will be stopped and restarted later.
 *
 * \param[in] mode New mode of output manager
 * \return 0 on successs
 */
int output_manager_set_mode(enum om_mode mode)
{
	if (conf->perman_odid_merge) {
		/* Nothing can be changed, permanent single manager mode enabled */
		if (mode == OM_MULTIPLE) {
			MSG_WARNING(msg_module, "Unable to change Output Manager mode. "
				"Single manager mode permanently enabled ('-M' argument)");
		}
		return 0;
	}

	if (conf->manager_mode == mode) {
		/* Mode is still the same */
		return 0;
	}

	if (conf->running) {
		MSG_DEBUG(msg_module, "Stopping Output Manager thread");
		rbuffer_write(conf->in_queue, NULL, 1);
		pthread_join(conf->thread_id, NULL);
	}

	/* Delete data managers */
	struct data_manager_config *aux_config = conf->data_managers;
	while (aux_config) {
		struct data_manager_config *tmp = aux_config;
		aux_config = aux_config->next;
		data_manager_close(&tmp);
	}

	conf->data_managers = NULL;
	conf->last = NULL;
	conf->manager_mode = mode;

	if (mode == OM_SINGLE) {
		MSG_INFO(msg_module, "Switching Output Manager to single manager mode");
	} else if (mode == OM_MULTIPLE) {
		MSG_INFO(msg_module, "Switching Output Manager to multiple manager mode");
	} else {
		/* Unknown mode */
	}

	if (conf->running) {
		/* Restart thread */
		int retval;
		MSG_DEBUG(msg_module, "Restarting Output Manager thread");
		retval = pthread_create(&(conf->thread_id), NULL,
				&output_manager_plugin_thread, (void *) conf);
		if (retval != 0) {
			MSG_ERROR(msg_module, "Unable to create Output Manager thread");
			free(conf);
			return -1;
		}
	}

	return 0;
}
Beispiel #2
0
static void read_cb(Stream *stream, RBuffer *buf, void *data, bool at_eof)
{
  if (at_eof) {
    input_eof = true;
  }

  assert(rbuffer_space(input_buffer) >= rbuffer_size(buf));
  RBUFFER_UNTIL_EMPTY(buf, ptr, len) {
    (void)rbuffer_write(input_buffer, ptr, len);
    rbuffer_consumed(buf, len);
  }
Beispiel #3
0
static void read_cb(RStream *rstream, void *data, bool at_eof)
{
  if (at_eof) {
    input_eof = true;
  }

  char *buf = rbuffer_read_ptr(read_buffer);
  size_t buf_size = rbuffer_pending(read_buffer);
  (void)rbuffer_write(input_buffer, buf, buf_size);
  rbuffer_consumed(read_buffer, buf_size);
}
Beispiel #4
0
size_t input_enqueue(String keys)
{
  char *ptr = keys.data;
  char *end = ptr + keys.size;

  while (rbuffer_space(input_buffer) >= 6 && ptr < end) {
    uint8_t buf[6] = { 0 };
    unsigned int new_size
        = trans_special((const uint8_t **)&ptr, (size_t)(end - ptr), buf, true,
                        true);

    if (new_size) {
      new_size = handle_mouse_event(&ptr, buf, new_size);
      rbuffer_write(input_buffer, (char *)buf, new_size);
      continue;
    }

    if (*ptr == '<') {
      char *old_ptr = ptr;
      // Invalid or incomplete key sequence, skip until the next '>' or *end.
      do {
        ptr++;
      } while (ptr < end && *ptr != '>');
      if (*ptr != '>') {
        // Incomplete key sequence, return without consuming.
        ptr = old_ptr;
        break;
      }
      ptr++;
      continue;
    }

    // copy the character, escaping CSI and K_SPECIAL
    if ((uint8_t)*ptr == CSI) {
      rbuffer_write(input_buffer, (char *)&(uint8_t){K_SPECIAL}, 1);
      rbuffer_write(input_buffer, (char *)&(uint8_t){KS_EXTRA}, 1);
      rbuffer_write(input_buffer, (char *)&(uint8_t){KE_CSI}, 1);
    } else if ((uint8_t)*ptr == K_SPECIAL) {
      rbuffer_write(input_buffer, (char *)&(uint8_t){K_SPECIAL}, 1);
      rbuffer_write(input_buffer, (char *)&(uint8_t){KS_SPECIAL}, 1);
      rbuffer_write(input_buffer, (char *)&(uint8_t){KE_FILLER}, 1);
    } else {
      rbuffer_write(input_buffer, ptr, 1);
    }
    ptr++;
  }

  size_t rv = (size_t)(ptr - keys.data);
  process_interrupts();
  return rv;
}
Beispiel #5
0
/**
 * \brief Close Ouput Manager and all Data Managers
 */
void output_manager_close(void *config)
{
	struct output_manager_config *manager = (struct output_manager_config *) config;
	struct data_manager_config *aux_config = NULL, *tmp = NULL;
	struct stat_thread *aux_thread = NULL, *tmp_thread = NULL;

	/* Stop Output Manager thread and free input buffer */
	if (manager->running) {
		rbuffer_write(manager->in_queue, NULL, 1);
		pthread_join(manager->thread_id, NULL);
		rbuffer_free(manager->in_queue);

		/* Close statistics thread */
		if (manager->stat_interval > 0) {
			manager->stats.done = 1;
			pthread_kill(manager->stat_thread, SIGUSR1);
			pthread_join(manager->stat_thread, NULL);
		}

		aux_config = manager->data_managers;

		/* Close all data managers */
		while (aux_config) {
			tmp = aux_config;
			aux_config = aux_config->next;
			data_manager_close(&tmp);
		}

		/* Free input_info_list */
		if (input_info_list) {
			struct input_info_node *aux_node = input_info_list;
			while (aux_node) {
				struct input_info_node *aux_node_rm = aux_node;
				aux_node = aux_node->next;
				free(aux_node_rm);
			}
		}

		/* Free all thread structures for statistics */
		aux_thread = manager->stats.threads;
		while (aux_thread) {
			tmp_thread = aux_thread;
			aux_thread = aux_thread->next;
			free(tmp_thread);
		}
	}

	free(manager);
}
/**
 * \brief Pass processed IPFIX message to the output queue.
 *
 * \param[in] config configuration structure
 * \param[in] message IPFIX message
 * \return 0 on success, negative value otherwise
 */
int pass_message(void *config, struct ipfix_message *message)
{
	struct ip_config *conf;
	int ret;

	conf = (struct ip_config *) config;

	if (message == NULL) {
		MSG_WARNING(msg_module, "NULL message from intermediate plugin, skipping.");
		return 0;
	}
	ret = rbuffer_write(conf->out_queue, message, 1);

	return ret;
}
Beispiel #7
0
/**
 * \brief Change process input queue
 */
int ip_change_in_queue(struct intermediate* conf, struct ring_buffer* in_queue)
{
	pthread_mutex_lock(&conf->in_q_mutex);
	
	conf->new_in = in_queue;
	rbuffer_write(conf->in_queue, NULL, 1);
	
	/* Wait for change */
	while (conf->in_queue != in_queue) {
		pthread_cond_wait(&conf->in_q_cond, &conf->in_q_mutex);
	}
	
	pthread_mutex_unlock(&conf->in_q_mutex);
	return 0;
}
Beispiel #8
0
/**
 * \brief Stop Intermediate Process
 */
int ip_stop(struct intermediate *conf)
{
	void *retval;
	int ret;
	
	if (!conf) {
		return -1;
	}

	/* wait for thread to terminate */
	rbuffer_write(conf->in_queue, NULL, 1);
	ret = pthread_join(conf->thread_id, &retval);

	if (ret != 0) {
		MSG_DEBUG(msg_module, "pthread_join() error");
	}

	return 0;
}
Beispiel #9
0
int32_t bus_terminal_send(bus_terminal_t* bt, const char* buf,
                          size_t buf_size, bus_addr_t to)
{
    struct bus_terminal_channel_t* btc;
    int32_t ret;

    if (!bt) return bus_err_fail;
    btc = (struct bus_terminal_channel_t*)idtable_get(bt->send_channels, to);
    // if no channel, then dynamic alloc one
    if (!btc) {
        ret = _bus_terminal_register_channel(bt, to, BUS_CHANNEL_DEFAULT_SIZE);
        if (ret != bus_ok) {
            return ret;
        }
    }
    btc = (struct bus_terminal_channel_t*)idtable_get(bt->send_channels, to);
    assert(btc);

    // send buffer
    ret = rbuffer_write(bus_terminal_channel_rbuffer(btc), buf, buf_size);
    return ret == 0 ? bus_ok : bus_err_send_fail;
}
Beispiel #10
0
/**
 * \brief Set new input queue
 */
void output_manager_set_in_queue(struct ring_buffer *in_queue)
{
	if (conf->in_queue == in_queue) {
		return;
	}
	
	if (conf->running) {
		/* If already running, control message must be sent */
		pthread_mutex_lock(&conf->in_q_mutex);
		
		conf->new_in = in_queue;
		rbuffer_write(conf->in_queue, NULL, 1);
		
		/* Wait for change */
		while (conf->in_queue != in_queue) {
			pthread_cond_wait(&conf->in_q_cond, &conf->in_q_mutex);
		}
		
		pthread_mutex_unlock(&conf->in_q_mutex);
	} else {
		conf->in_queue = in_queue;
	}
}
Beispiel #11
0
size_t input_enqueue_mouse(int code, uint8_t modifier,
                           int grid, int row, int col)
{
  modifier |= check_multiclick(code, grid, row, col);
  uint8_t buf[7], *p = buf;
  if (modifier) {
    p[0] = K_SPECIAL;
    p[1] = KS_MODIFIER;
    p[2] = modifier;
    p += 3;
  }
  p[0] = K_SPECIAL;
  p[1] = KS_EXTRA;
  p[2] = (uint8_t)code;

  mouse_grid = grid;
  mouse_row = row;
  mouse_col = col;

  size_t written = 3 + (size_t)(p-buf);
  rbuffer_write(input_buffer, (char *)buf, written);
  return written;
}
Beispiel #12
0
/**
 * \brief Output Managers thread
 *
 * @param[in] config configuration structure
 * @return NULL
 */
static void *output_manager_plugin_thread(void* config)
{
	struct data_manager_config *data_config = NULL;
	struct ipfix_message* msg = NULL;
	unsigned int index;

	conf = (struct output_manager_config *) config;
	index = conf->in_queue->read_offset;

	/* set the thread name to reflect the configuration */
	prctl(PR_SET_NAME, "ipfixcol OM", 0, 0, 0);

	/* loop will break upon receiving NULL from buffer */
	while (1) {
		/* get next data */
		index = -1;
		msg = rbuffer_read(conf->in_queue, &index);

		if (!msg) {
			rbuffer_remove_reference(conf->in_queue, index, 1);
			if (conf->new_in) {
				/* Set new input queue */
				conf->in_queue = (struct ring_buffer *) conf->new_in;
				conf->new_in = NULL;
				pthread_cond_signal(&conf->in_q_cond);
				continue;
			}
			
			/* End manager */
			break;
		}

		/* get appropriate data manager's config according to Observation domain ID */
		data_config = get_data_mngmt_config (msg->input_info->odid, conf->data_managers);
		if (data_config == NULL) {
			/*
			 * no data manager config for this observation domain ID found -
			 * we have a new observation domain ID, so create new data manager for
			 * it
			 */
			data_config = data_manager_create(msg->input_info->odid, conf->storage_plugins);
			if (data_config == NULL) {
				MSG_WARNING(msg_module, "[%u] Unable to create Data Manager; skipping data...",
						msg->input_info->odid);
				rbuffer_remove_reference(conf->in_queue, index, 1);
				continue;
			}

			/* add config to data_mngmts structure */
			output_manager_insert(conf, data_config);

			MSG_NOTICE(msg_module, "[%u] Data Manager created", msg->input_info->odid);
		}

		if (msg->source_status == SOURCE_STATUS_NEW) {
			/* New source, increment reference counter */
			MSG_DEBUG(msg_module, "[%u] New source", data_config->observation_domain_id);
			data_config->references++;
		} else if (msg->source_status == SOURCE_STATUS_CLOSED) {
			/* Source closed, decrement reference counter */
			MSG_DEBUG(msg_module, "[%u] Closed source", data_config->observation_domain_id);
			data_config->references--;

			if (data_config->references == 0) {
				/* No reference for this ODID, close DM */
				MSG_DEBUG(msg_module, "[%u] No source; releasing templates...", data_config->observation_domain_id);
				output_manager_remove(conf, data_config);
			}

			rbuffer_remove_reference(conf->in_queue, index, 1);
			continue;
		}

		__sync_fetch_and_add(&(conf->packets), 1);
		__sync_fetch_and_add(&(conf->data_records), msg->data_records_count);

		/* Check for lost data records */
		uint32_t seq_number = ntohl(msg->pkt_header->sequence_number);

		// Set sequence number during first iteration
		if (conf->first_seq == 0 && conf->last_seq == 0) {
			conf->first_seq = seq_number;
		} else if (seq_number < conf->first_seq) {
			// Sequence number resetted (modulo 2^32 = 4294967296)
			conf->first_seq = seq_number;
			uint8_t delta_seq = 4294967296 - conf->last_seq + seq_number;

			// Check for sequence number gap
			if (delta_seq > msg->data_records_count) {
				__sync_fetch_and_add(&(conf->lost_data_records), delta_seq - msg->data_records_count);
			}
		} else if (seq_number > conf->first_seq) {
			// Check for sequence number gap
			if (seq_number - msg->data_records_count > conf->last_seq) {
				__sync_fetch_and_add(&(conf->lost_data_records), seq_number - msg->data_records_count - conf->last_seq);
			}
		} else {
			// Do nothing
		}

		conf->last_seq = seq_number;
		
		/* Write data into input queue of Storage Plugins */
		if (rbuffer_write(data_config->store_queue, msg, data_config->plugins_count) != 0) {
			MSG_WARNING(msg_module, "[%u] Unable to write into Data Manager's input queue; skipping data...", data_config->observation_domain_id);
			rbuffer_remove_reference(conf->in_queue, index, 1);
			free(msg);
			continue;
		}
		
		/* Remove data from queue (without deallocating) */
		rbuffer_remove_reference(conf->in_queue, index, 0);
	}

	MSG_NOTICE(msg_module, "Closing Output Manager thread");

	return (void *) 0;
}
Beispiel #13
0
/**
 * \brief Output Manager thread
 *
 * @param[in] config configuration structure
 * @return NULL
 */
static void *output_manager_plugin_thread(void* config)
{
	struct data_manager_config *data_config = NULL;
	struct ipfix_message* msg = NULL;
	unsigned int index;
	uint32_t odid;

	conf = (struct output_manager_config *) config;
	index = conf->in_queue->read_offset;

	/* Set thread name to reflect the configuration */
	prctl(PR_SET_NAME, "ipfixcol OM", 0, 0, 0);

	/* loop will break upon receiving NULL from buffer */
	while (1) {
		/* get next data */
		index = -1;
		msg = rbuffer_read(conf->in_queue, &index);

		if (!msg) {
			rbuffer_remove_reference(conf->in_queue, index, 1);
			if (conf->new_in) {
				/* Set new input queue */
				conf->in_queue = (struct ring_buffer *) conf->new_in;
				conf->new_in = NULL;
				pthread_cond_signal(&conf->in_q_cond);
				continue;
			}

			/* Stop manager */
			break;
		}

		odid = (conf->perman_odid_merge || conf->manager_mode == OM_SINGLE)
				? 0 : msg->input_info->odid;

		/* Get appropriate data Manager config according to ODID */
		data_config = get_data_mngmt_config(odid, conf->data_managers);
		if (data_config == NULL) {
			/*
			 * No data manager config for this observation domain ID found -
			 * we have a new observation domain ID, so create new data manager for
			 * it
			 */
			data_config = data_manager_create(odid, conf->storage_plugins);
			if (data_config == NULL) {
				MSG_WARNING(msg_module, "[%u] Unable to create Data Manager; skipping data...",
						odid);
				rbuffer_remove_reference(conf->in_queue, index, 1);
				continue;
			}

			/* Add config to data_mngmts structure */
			output_manager_insert(conf, data_config);
			MSG_INFO(msg_module, "[%u] Data Manager created", odid);
		}

		if (msg->source_status == SOURCE_STATUS_NEW) {
			/* New source, increment reference counter */
			MSG_DEBUG(msg_module, "[%u] New source", data_config->observation_domain_id);
			data_config->references++;
			/* Add input info for the statistics thread to read */
			add_input_info(msg->input_info);
		} else if (msg->source_status == SOURCE_STATUS_CLOSED) {
			/* Source closed, decrement reference counter */
			MSG_DEBUG(msg_module, "[%u] Closed source", data_config->observation_domain_id);
			data_config->references--;

			/* Remove a reference to a template record */
			uint32_t original_odid = msg->input_info->odid;
			uint32_t source_crc = preprocessor_compute_crc(msg->input_info);

			if (tm_source_unregister(template_mgr, original_odid, source_crc)) {
				MSG_ERROR(msg_module, "[%u] Unable to unregister the source from the main template manager!", data_config->observation_domain_id);
			}

			/* Remove input_info from statistics */
			remove_input_info(msg->input_info);

			if (data_config->references == 0) {
				/* No reference for this ODID, close DM */
				MSG_DEBUG(msg_module, "[%u] No source; releasing templates...", data_config->observation_domain_id);
				output_manager_remove(conf, data_config);
			}

			rbuffer_remove_reference(conf->in_queue, index, 1);
			continue;
		}

		/* Write data into input queue of Storage Plugins */
		if (rbuffer_write(data_config->store_queue, msg, data_config->plugins_count) != 0) {
			MSG_WARNING(msg_module, "[%u] Unable to write into Data Manager input queue; skipping data...", data_config->observation_domain_id);
			rbuffer_remove_reference(conf->in_queue, index, 1);
			free(msg);
			continue;
		}

		/* Remove data from queue (without memory deallocation) */
		rbuffer_remove_reference(conf->in_queue, index, 0);
	}

	MSG_INFO(msg_module, "Closing Output Manager thread");

	return (void *) 0;
}