Пример #1
0
struct stream* stream_alloc(uint32_t max_buff_size, struct conntrack_entry *ce, unsigned int flags, int (*handler) (struct conntrack_entry *ce, struct packet *p, struct proto_process_stack *stack, unsigned int stack_index)) {
	
	struct stream *res = malloc(sizeof(struct stream));
	if (!res) {
		pom_oom(sizeof(struct stream));
		return NULL;
	}

	memset(res, 0, sizeof(struct stream));
	
	res->max_buff_size = max_buff_size;
	res->ce = ce;
	if (pthread_mutex_init(&res->lock, NULL)) {
		pomlog(POMLOG_ERR "Error while initializing stream lock : %s", pom_strerror(errno));
		free(res);
		return NULL;
	}
	if (pthread_mutex_init(&res->wait_lock, NULL)) {
		pomlog(POMLOG_ERR "Error while initializing stream wait lock : %s", pom_strerror(errno));
		free(res);
		return NULL;
	}

	res->flags = flags;
	res->handler = handler;

	debug_stream("thread %p, entry %p, allocated", pthread_self(), res);

	return res;
}
Пример #2
0
void registry_perf_set_update_hook(struct registry_perf *p, int (*update_hook) (uint64_t *cur_val, void *priv), void *hook_priv) {

	if (p->type == registry_perf_type_timeticks) {
		pomlog(POMLOG_ERR "Trying to set an update hook on a timeticks perf");
		return;
	}

	if (!update_hook) {
		if (p->update_hook) {
			int res = pthread_mutex_destroy(&p->hook_lock);
			if (res) {
				pomlog(POMLOG_ERR "Error while destroying the perf hook lock : %s", pom_strerror(res));
				abort();
			}
		}
		p->update_hook = NULL;
		p->hook_priv = NULL;
		return;
	}

	if (!p->update_hook) {
		int res = pthread_mutex_init(&p->hook_lock, NULL);
		if (res) {
			pomlog(POMLOG_ERR "Error while initializing the perf hook lock : %s", pom_strerror(res));
			abort();
		}
	}

	p->update_hook = update_hook;
	p->hook_priv = hook_priv;

}
Пример #3
0
struct packet_stream* packet_stream_alloc(uint32_t start_seq, uint32_t start_ack, int direction, uint32_t max_buff_size, struct conntrack_entry *ce, unsigned int flags) {
	
	struct packet_stream *res = malloc(sizeof(struct packet_stream));
	if (!res) {
		pom_oom(sizeof(struct packet_stream));
		return NULL;
	}

	memset(res, 0, sizeof(struct packet_stream));
	
	int rev_direction = POM_DIR_REVERSE(direction);
	res->cur_seq[direction] = start_seq;
	res->cur_ack[direction] = start_ack;
	res->cur_seq[rev_direction] = start_ack;
	res->cur_ack[rev_direction] = start_seq;
	res->max_buff_size = max_buff_size;
	res->ce = ce;
	if (pthread_mutex_init(&res->lock, NULL)) {
		pomlog(POMLOG_ERR "Error while initializing stream lock : %s", pom_strerror(errno));
		free(res);
		return NULL;
	}
	if (pthread_mutex_init(&res->wait_lock, NULL)) {
		pomlog(POMLOG_ERR "Error while initializing stream wait lock : %s", pom_strerror(errno));
		free(res);
		return NULL;
	}

	res->flags = flags;

	debug_stream("thread %p, entry %p, allocated, start_seq %u, start_ack %u, direction %u", pthread_self(), res, start_seq, start_ack, direction);

	return res;
}
Пример #4
0
int mod_load_all() {

	char *path = getenv(MOD_LIBDIR_ENV_VAR);
	if (!path)
		path = POM_LIBDIR;

	DIR *d;
	d = opendir(path);

	if (!d) {
		pomlog(POMLOG_ERR "Could not open directory %s for browsing : %s", path, pom_strerror(errno));
		return POM_ERR;
	}

	struct dirent tmp, *dp;
	while (1) {
		if (readdir_r(d, &tmp, &dp) < 0) {
			pomlog(POMLOG_ERR "Error while reading directory entry : %s", pom_strerror(errno));
			closedir(d);
			return POM_ERR;
		}
		if (!dp) // EOF
			break;


		size_t len = strlen(dp->d_name);
		if (len < strlen(POM_LIB_EXT) + 1)
			continue;
		if (!strcmp(dp->d_name + strlen(dp->d_name) - strlen(POM_LIB_EXT), POM_LIB_EXT)) {
			

			char *name = strdup(dp->d_name);
			if (!name) {
				pom_oom(strlen(dp->d_name));
				closedir(d);
				return POM_ERR;
			}
			*(name + strlen(dp->d_name) - strlen(POM_LIB_EXT)) = 0;

			// Check if a dependency already loaded this module
			pom_mutex_lock(&mod_reg_lock);
			struct mod_reg *tmp;
			for (tmp = mod_reg_head; tmp && strcmp(name, tmp->name); tmp = tmp->next);
			if (tmp) {
				pom_mutex_unlock(&mod_reg_lock);
				free(name);
				continue;
			}
			pom_mutex_unlock(&mod_reg_lock);

			mod_load(name);
			free(name);
		}
	}
	closedir(d);

	return POM_OK;

}
Пример #5
0
static int input_kismet_drone_open(struct input *i) {
	
	struct input_kismet_drone_priv *priv = i->priv;

	char *host = PTYPE_STRING_GETVAL(priv->p_host);

	char *port = ptype_print_val_alloc(priv->p_port, NULL);
	if (!port)
		return POM_ERR;

	struct addrinfo hints = { 0 };
	//hints.ai_family = AF_UNSPEC;
	hints.ai_family = AF_INET; // kismet_drone seem to only listen on ipv4 address
	hints.ai_socktype = SOCK_STREAM;
	hints.ai_protocol = 0;
	hints.ai_flags = AI_ADDRCONFIG;

	struct addrinfo *res = NULL;
	int err = getaddrinfo(host, port, &hints, &res);

	free(port);

	if (err) {
		pomlog(POMLOG_ERR "Error while resolving hostname %s : %s", host, gai_strerror(err));
		return POM_ERR;
	}


	priv->fd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);

	if (priv->fd == -1) {
		freeaddrinfo(res);
		pomlog(POMLOG_ERR "Error while creating socket : %s", pom_strerror(errno));
		return POM_ERR;
	}
	
	if (connect(priv->fd, res->ai_addr, res->ai_addrlen)) {
		freeaddrinfo(res);
		close(priv->fd);
		priv->fd = -1;
		pomlog(POMLOG_ERR "Error while connecting to Kismet drone : %s", pom_strerror(errno));
		return POM_ERR;
	}

	freeaddrinfo(res);

	pomlog("Connection established to Kismet drone %s:%u", host, *PTYPE_UINT16_GETVAL(priv->p_port));

	return POM_OK;
}
Пример #6
0
int output_tap_open(void *output_priv) {

	struct output_tap_priv *priv = output_priv;
	
	priv->fd = open("/dev/net/tun", O_RDWR | O_SYNC);
	if (priv->fd < 0) {
		pomlog(POMLOG_ERR "Error while opening the tap device : %s", pom_strerror(errno));
		return POM_ERR;
	}

	struct ifreq ifr;
	memset(&ifr, 0, sizeof(struct ifreq));
	ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
	strncpy(ifr.ifr_name, PTYPE_STRING_GETVAL(priv->p_ifname), IFNAMSIZ);
	if (ioctl(priv->fd, TUNSETIFF, (void *) &ifr) < 0) {
		pomlog(POMLOG_ERR "Unable to setup tap device %s : %s", PTYPE_STRING_GETVAL(priv->p_ifname), pom_strerror(errno));
		return POM_ERR;
	}

	if (ioctl(priv->fd, TUNSETPERSIST, *PTYPE_BOOL_GETVAL(priv->p_persistent)) < 0) {
		pomlog(POMLOG_WARN "Unable to set persistent mode to tap device %s : %s", PTYPE_STRING_GETVAL(priv->p_ifname), pom_strerror(errno));
	}

	priv->listener = proto_packet_listener_register(proto_get("ethernet"), 0, priv, output_tap_pkt_process, priv->filter);
	if (!priv->listener)
		goto err;

	return POM_OK;

err:
	close(priv->fd);
	priv->fd = -1;
	return POM_ERR;
}
Пример #7
0
int conntrack_table_cleanup(struct conntrack_tables *ct) {

	if (!ct)
		return POM_OK;


	if (ct->table) {
		conntrack_table_empty(ct);
		free(ct->table);
	}

	if (ct->locks) {
		unsigned int i;
		for (i = 0; i < ct->table_size; i++) {
			int res = pthread_mutex_destroy(&ct->locks[i]);
			if (res) {
				pomlog(POMLOG_WARN "Error while destroying a hash lock : %s", pom_strerror(errno));
			}
		}
		free(ct->locks);
	}


	free(ct);

	return POM_OK;
}
Пример #8
0
void core_resume_processing() {

	if (pthread_rwlock_unlock(&core_processing_lock)) {
		pomlog(POMLOG_ERR "Error while locking core processing lock : %s", pom_strerror(errno));
		abort();
	}
}
Пример #9
0
void core_pause_processing() {

	int res = pthread_rwlock_wrlock(&core_processing_lock);
	if (res) {
		pomlog(POMLOG_ERR "Error while locking core processing lock : %s", pom_strerror(res));
		abort();
	}
}
Пример #10
0
int core_cleanup(int emergency_cleanup) {

	core_run = 0;


	int i;
	for (i = 0; i < CORE_PROCESS_THREAD_MAX && core_processing_threads[i]; i++) {
		struct core_processing_thread *t = core_processing_threads[i];
		int res = pthread_cond_signal(&t->pkt_queue_cond);
		if (res) {
			pomlog(POMLOG_ERR "Error while signaling the restart condition : %s", pom_strerror(res));
			abort();
		}
		pthread_join(t->thread, NULL);
		res = pthread_mutex_destroy(&t->pkt_queue_lock);
		if (res)
			pomlog(POMLOG_WARN "Error while destroying a processing thread lock : %s", pom_strerror(res));
		
		res = pthread_cond_destroy(&t->pkt_queue_cond);
		if (res)
			pomlog(POMLOG_WARN "Error while destroying a processing thread condition : %s", pom_strerror(res));


		struct core_packet_queue *tmp = NULL;
		while (t->pkt_queue_head) {
			tmp = t->pkt_queue_head;
			t->pkt_queue_head = tmp->next;
			// packet_pool_cleanup() was already called when the thread stopped
			// packet_pool_release(tmp->pkt);
			free(tmp);
			pomlog(POMLOG_WARN "A packet was still in a thread's queue");
		}

		while (t->pkt_queue_unused) {
			tmp = t->pkt_queue_unused;
			t->pkt_queue_unused = tmp->next;
			// packet_pool_cleanup() was already called when the thread stopped
			// packet_pool_release(tmp->pkt);
			free(tmp);
		}

		free(t);
	}

	return POM_OK;
}
Пример #11
0
int core_cleanup(int emergency_cleanup) {

	core_run = 0;

	if (!emergency_cleanup) {
		while (core_pkt_queue_head) {
			pomlog("Waiting for all the packets to be processed");
			if (pthread_cond_broadcast(&core_pkt_queue_restart_cond)) {
				pomlog(POMLOG_ERR "Error while signaling the restart condition : %s", pom_strerror(errno));
				return POM_ERR;
			}
			sleep(1);
		}
	}

	if (pthread_cond_broadcast(&core_pkt_queue_restart_cond)) {
		pomlog(POMLOG_ERR "Error while signaling the restart condition : %s", pom_strerror(errno));
		return POM_ERR;
	}

	int i;
	for (i = 0; i < CORE_PROCESS_THREAD_MAX && core_processing_threads[i]; i++) {
		pthread_join(core_processing_threads[i]->thread, NULL);
		free(core_processing_threads[i]);
	}

	pthread_cond_destroy(&core_pkt_queue_restart_cond);

	while (core_pkt_queue_head) {
		struct core_packet_queue *tmp = core_pkt_queue_head;
		core_pkt_queue_head = tmp->next;
		packet_pool_release(tmp->pkt);
		free(tmp);
		pomlog(POMLOG_WARN "A packet was still in the buffer");
	}

	while (core_pkt_queue_unused) {
		struct core_packet_queue *tmp = core_pkt_queue_unused;
		core_pkt_queue_unused = tmp->next;
		free(tmp);
	}

	
	return POM_OK;
}
Пример #12
0
int proto_cleanup() {

    struct proto *proto;
    for (proto = proto_head; proto; proto = proto->next) {

        if (proto->info->cleanup && proto->info->cleanup(proto->priv) == POM_ERR)
            pomlog(POMLOG_WARN "Error while cleaning up protocol %s", proto->info->name);
        conntrack_table_cleanup(proto->ct);

        mod_refcount_dec(proto->info->mod);
    }

    while (proto_head) {
        proto = proto_head;
        proto_head = proto->next;

        int res = pthread_rwlock_destroy(&proto->listeners_lock);
        if (res)
            pomlog(POMLOG_ERR "Error while destroying the listners lock : %s", pom_strerror(res));
        res = pthread_rwlock_destroy(&proto->expectation_lock);
        if (res)
            pomlog(POMLOG_ERR "Error while destroying the listners lock : %s", pom_strerror(res));


        free(proto);
    }

    if (proto_registry_class)
        registry_remove_class(proto_registry_class);
    proto_registry_class = NULL;

    while (proto_number_class_head) {
        struct proto_number_class *cls = proto_number_class_head;
        proto_number_class_head = cls->next;
        while (cls->nums) {
            struct proto_number *num = cls->nums;
            cls->nums = num->next;
            free(num);
        }
        free(cls->name);
        free(cls);
    }

    return POM_OK;
}
Пример #13
0
int packet_info_pool_init(struct packet_info_pool *pool) {

	if (pthread_mutex_init(&pool->lock, NULL)) {
		pomlog(POMLOG_ERR "Error while initializing the pkt_info_pool lock : ", pom_strerror(errno));
		return POM_ERR;
	}

	return POM_OK;
}
Пример #14
0
int core_set_state(enum core_state state) {

	int res = POM_OK;

	pom_mutex_lock(&core_state_lock);

	if (core_cur_state == state) {
		pomlog(POMLOG_DEBUG "Core state unchanged : %u", state);
		pom_mutex_unlock(&core_state_lock);
		return POM_OK;
	}

	core_cur_state = state;
	pomlog(POMLOG_DEBUG "Core state changed to %u", state);
	if (pthread_cond_broadcast(&core_state_cond)) {
		pomlog(POMLOG_ERR "Unable to signal core state condition : %s", pom_strerror(errno));
		pom_mutex_unlock(&core_state_lock);
		return POM_ERR;
	}
	pom_mutex_unlock(&core_state_lock);

	if (state == core_state_idle) {

		res = core_processing_stop();

		ptime now = pom_gettimeofday();

		int i;
		for (i = 0; i < CORE_PROCESS_THREAD_MAX; i++)
			core_clock[i] = 0;

		ptime runtime = now - core_start_time;

		pomlog(POMLOG_INFO "Core was running for %u.%06u secs", pom_ptime_sec(runtime), pom_ptime_usec(runtime));

	} else if (state == core_state_running) {
		core_start_time = pom_gettimeofday();
		res = core_processing_start();
	} else if (state == core_state_finishing) {
		// Signal all the threads
		unsigned int i;
		for (i = 0; i < core_num_threads; i++) {
			struct core_processing_thread *t = core_processing_threads[i];

			pom_mutex_lock(&t->pkt_queue_lock);
			int res = pthread_cond_broadcast(&t->pkt_queue_cond);
			pom_mutex_unlock(&t->pkt_queue_lock);
			if (res) {
				pomlog(POMLOG_ERR "Error while broadcasting restart condition after set state");
				abort();
			}
		}
	}
	return res;
}
Пример #15
0
void core_wait_state(enum core_state state) {
	pom_mutex_lock(&core_state_lock);
	while (core_cur_state != state) {
		if (pthread_cond_wait(&core_state_cond, &core_state_lock)) {
			pomlog(POMLOG_ERR "Error while waiting for core cond : %s", pom_strerror(errno));
			abort();
			break;
		}
	}
	pom_mutex_unlock(&core_state_lock);
}
Пример #16
0
int output_file_pload_write(void *pload_instance_priv, void *data, size_t len) {


	struct output_file_pload_priv *ppriv = pload_instance_priv;
	int res = pom_write(ppriv->fd, data, len);
	if (res == POM_ERR)
		pomlog(POMLOG_ERR "Error while writing to file %s : %s", ppriv->filename, pom_strerror(errno));

	return res;

}
Пример #17
0
int stream_cleanup(struct stream *stream) {


	if (stream->wait_list_head) {
		pomlog(POMLOG_ERR "Internal error, cleaning up stream while packets still present!");
		return POM_ERR;
	}

	while (stream->head[0] || stream->head[1]) {
		if (stream_force_dequeue(stream) == POM_ERR) {
			pomlog(POMLOG_ERR "Error while processing remaining packets in the stream");
			break;
		}
	}

	conntrack_delayed_cleanup(stream->ce, 0, stream->last_ts);

	int res = pthread_mutex_destroy(&stream->lock);
	if (res){
		pomlog(POMLOG_ERR "Error while destroying stream lock : %s", pom_strerror(res));
	}

	res = pthread_mutex_destroy(&stream->wait_lock);
	if (res){
		pomlog(POMLOG_ERR "Error while destroying stream wait lock : %s", pom_strerror(res));
	}

	while (stream->wait_list_unused) {
		struct stream_thread_wait *tmp = stream->wait_list_unused;
		stream->wait_list_unused = tmp->next;
		if (pthread_cond_destroy(&tmp->cond))
			pomlog(POMLOG_WARN "Error while destroying list condition");
		free(tmp);
	}
	
	free(stream);

	debug_stream("thread %p, entry %p, released", pthread_self(), stream);

	return POM_OK;
}
Пример #18
0
int output_file_pload_write(void *output_priv, void *pload_instance_priv, void *data, size_t len) {

	struct output_file_priv *priv = output_priv;
	struct output_file_pload_priv *ppriv = pload_instance_priv;
	int res = pom_write(ppriv->fd, data, len);
	if (res == POM_ERR)
		pomlog(POMLOG_ERR "Error while writing to file %s : %s", ppriv->filename, pom_strerror(errno));
	else if (priv && priv->perf_bytes_written)
		registry_perf_inc(priv->perf_bytes_written, len);
		

	return res;

}
Пример #19
0
int core_set_state(enum core_state state) {

	int res = POM_OK;

	pom_mutex_lock(&core_state_lock);
	core_cur_state = state;
	pomlog(POMLOG_DEBUG "Core state changed to %u", state);
	if (pthread_cond_broadcast(&core_state_cond)) {
		pomlog(POMLOG_ERR "Unable to signal core state condition : %s", pom_strerror(errno));
		pom_mutex_unlock(&core_state_lock);
		return POM_ERR;
	}

	if (state == core_state_idle) {

		res = core_processing_stop();

		struct timeval now;
		gettimeofday(&now, NULL);
		if (now.tv_usec < core_start_time.tv_usec) {
			now.tv_sec--;
			now.tv_usec += 1000000;
		}
		pom_mutex_lock(&core_clock_lock);
		memset(&core_clock, 0, sizeof(struct timeval));
		pom_mutex_unlock(&core_clock_lock);


		now.tv_usec -= core_start_time.tv_usec;
		now.tv_sec -= core_start_time.tv_sec;
		pomlog(POMLOG_INFO "Core was running for %u.%06u secs", now.tv_sec, now.tv_usec);

	} else if (state == core_state_running) {
		gettimeofday(&core_start_time, NULL);
		res = core_processing_start();
	} else if (state == core_state_finishing) {
		//pom_mutex_lock(&core_pkt_queue_mutex);
		if (pthread_cond_broadcast(&core_pkt_queue_restart_cond)) {
			pom_mutex_unlock(&core_pkt_queue_mutex);
			pom_mutex_unlock(&core_state_lock);
			pomlog(POMLOG_ERR "Error while broadcasting restart condition after set state");
			return POM_ERR;
		}
		//pom_mutex_unlock(&core_pkt_queue_mutex);
	}
	pom_mutex_unlock(&core_state_lock);
	return res;
}
Пример #20
0
static int input_kismet_drone_discard_bytes(struct input_kismet_drone_priv *priv, size_t len) {

	// Discard whatever command we dont need/support
	char buffer[256];
	size_t r = len;
	while (r > 0) {
		size_t rlen = sizeof(buffer);
		if (rlen > r)
			rlen = r;
		size_t res = read(priv->fd, buffer, rlen);
		if (res < 0) {
			pomlog(POMLOG_ERR "Read error : %s", pom_strerror(errno));
			return POM_ERR;
		}
		r -= res;
	}
	return POM_OK;
}
Пример #21
0
int addon_log_xml_close(void *output_priv) {

    struct output_log_xml_priv *priv = output_priv;

    if (priv->fd == -1) {
        pomlog(POMLOG_ERR "Output already stopped");
        return POM_ERR;
    }

    if (close(priv->fd)) {
        pomlog(POMLOG_ERR "Error while closing log file : %s", pom_strerror(errno));
        return POM_ERR;
    }

    priv->fd = -1;

    return POM_OK;
}
Пример #22
0
struct conntrack_tables* conntrack_table_alloc(size_t table_size, int has_rev) {

	struct conntrack_tables *ct = malloc(sizeof(struct conntrack_tables));
	if (!ct) {
		pom_oom(sizeof(struct conntrack_tables));
		return NULL;
	}
	memset(ct, 0, sizeof(struct conntrack_tables));


	size_t size = sizeof(struct conntrack_list) * table_size;
	ct->table = malloc(size);
	if (!ct->table) {
		pom_oom(size);
		goto err;
	}
	memset(ct->table, 0, size);

	size = sizeof(pthread_mutex_t) *table_size;
	ct->locks = malloc(size);
	if (!ct->locks) {
		pom_oom(size);
		goto err;

	}

	unsigned int i;

	for (i = 0; i < table_size; i++) {
		int res = pthread_mutex_init(&ct->locks[i], NULL);
		if (res) {
			pomlog(POMLOG_ERR "Could not initialize conntrack hash lock : %s", pom_strerror(res));
			goto err;
		}
	}
	ct->table_size = table_size;

	return ct;

err:
	conntrack_table_cleanup(ct);
	return NULL;
}
Пример #23
0
int conntrack_timer_cleanup(struct conntrack_timer *t) {

#ifdef DEBUG_CONNTRACK
	int res = pthread_mutex_lock(&t->ce->lock);

	if (!res) {
		pomlog(POMLOG_ERR "Internal error, conntrack not locked when timer cleaned up");
		pom_mutex_unlock(&t->ce->lock);
	} else if (res != EDEADLK) {
		pomlog(POMLOG_ERR "Error while locking timer lock : %s", pom_strerror(errno));
		abort();
	}
#endif

	timer_cleanup(t->timer);
	free(t);
	return POM_OK;

}
Пример #24
0
static int input_kismet_drone_close(struct input *i) {

	struct input_kismet_drone_priv *priv = i->priv;
	if (priv->fd != -1) {
		if (close(priv->fd))
			pomlog(POMLOG_WARN "Error while closing socket to kismet_drone : %s", pom_strerror(errno));
		priv->fd = -1;
	}

	while (priv->srcs) {
		struct kismet_drone_source *src = priv->srcs;
		priv->srcs = src->next;
		free(src->name);
		free(src->interface);
		free(src->type);
		free(src);
	}

	return POM_OK;
}
Пример #25
0
xmlrpc_value *xmlrpccmd_core_serial_poll(xmlrpc_env * const envP, xmlrpc_value * const paramArrayP, void * const userData) {


	uint32_t last_serial = 0;
	xmlrpc_decompose_value(envP, paramArrayP, "(i)", &last_serial);
	if (envP->fault_occurred)
		return NULL;
	

	pom_mutex_lock(&xmlrpccmd_serial_lock);
	if (last_serial == xmlrpccmd_serial) {
		// Wait for update
		if (pthread_cond_wait(&xmlrpccmd_serial_cond, &xmlrpccmd_serial_lock)) {
			xmlrpc_faultf(envP, "Error while waiting for serial condition : %s", pom_strerror(errno));
			abort();
			return NULL;
		}
	
	}

	last_serial = xmlrpccmd_serial;
	pom_mutex_unlock(&xmlrpccmd_serial_lock);

	registry_lock();
	pomlog_rlock();

	struct pomlog_entry *last_log = pomlog_get_tail();
	
	xmlrpc_value *res = xmlrpc_build_value(envP, "{s:i,s:i,s:i}",
						"main", last_serial,
						"registry", registry_serial_get(),
						"log", last_log->id);

	pomlog_unlock();
	registry_unlock();

	return res;

}
Пример #26
0
struct conntrack_session *conntrack_session_get(struct conntrack_entry *ce) {

	if (!ce->session) {
		ce->session = malloc(sizeof(struct conntrack_session));
		if (!ce->session) {
			pom_oom(sizeof(struct conntrack_session));
			return NULL;
		}
		memset(ce->session, 0, sizeof(struct conntrack_session));

		if (pthread_mutex_init(&ce->session->lock, NULL)) {
			pomlog(POMLOG_ERR "Error while initializing session mutex : %s", pom_strerror(errno));
			free(ce->session);
			ce->session = NULL;
			return NULL;
		}
		ce->session->refcount++;
	}
	
	pom_mutex_lock(&ce->session->lock);

	return ce->session;
}
Пример #27
0
int addon_log_xml_open(void *output_priv) {

    struct output_log_xml_priv *priv = output_priv;

    if (priv->fd != -1) {
        pomlog(POMLOG_ERR "Output log_xml already started");
        return POM_ERR;
    }

    char *filename = PTYPE_STRING_GETVAL(priv->p_filename);
    if (!strlen(filename)) {
        pomlog(POMLOG_ERR "You must specify a filename where to log the output");
        return POM_ERR;
    }

    priv->fd = open(filename, O_CREAT | O_WRONLY | O_APPEND, S_IRUSR | S_IWUSR | S_IRGRP);
    if (priv->fd == -1) {
        pomlog(POMLOG_ERR "Error while opening log file \"%s\" : %s", filename, pom_strerror(errno));
        return POM_ERR;
    }

    return POM_OK;

}
Пример #28
0
int timers_process() {


	static int processing = 0;

	int res = pthread_mutex_trylock(&timer_main_lock);
	if (res == EBUSY) {
		// Already locked, give up
		return POM_OK;
	} else if (res) {
		// Something went wrong
		pomlog(POMLOG_ERR "Error while trying to lock the main timer lock : %s", pom_strerror(res));
		abort();
		return POM_ERR;
	}

	// Another thread is already processing the timers, drop out
	if (processing) {
		pom_mutex_unlock(&timer_main_lock);
		return POM_OK;
	}

	processing = 1;

	ptime now = core_get_clock();

	struct timer_queue *tq;
	tq = timer_queues;

	while (tq) {
		while (tq->head && (tq->head->expires < now)) {
				
			// Dequeue the timer
			struct timer *tmp = tq->head;
			tq->head = tq->head->next;
			if (tq->head)
				tq->head->prev = NULL;
			else
				tq->tail = NULL;

			tmp->next = NULL;
			tmp->prev = NULL;
			tmp->queue = NULL;
			pom_mutex_unlock(&timer_main_lock);
			registry_perf_dec(perf_timer_queued, 1);

			// Process it
			debug_timer( "Timer 0x%lx reached. Starting handler ...", (unsigned long) tmp);
			if ((*tmp->handler) (tmp->priv, now) != POM_OK) {
				return POM_ERR;
			}

			registry_perf_inc(perf_timer_processed, 1);

			pom_mutex_lock(&timer_main_lock);

		}
		tq = tq->next;

	}

	processing = 0;

	pom_mutex_unlock(&timer_main_lock);

	return POM_OK;
}
Пример #29
0
int proto_register(struct proto_reg_info *reg_info) {

    if (reg_info->api_ver != PROTO_API_VER) {
        pomlog(POMLOG_ERR "Cannot register proto as API version differ : expected %u got %u", PROTO_API_VER, reg_info->api_ver);
        return POM_ERR;
    }


    // Check if the protocol already exists
    struct proto *proto;
    for (proto = proto_head; proto && strcmp(proto->info->name, reg_info->name); proto = proto->next);
    if (proto)
        return POM_ERR;

    // Allocate the protocol
    proto = malloc(sizeof(struct proto));
    if (!proto) {
        pom_oom(sizeof(struct proto));
        return POM_ERR;
    }

    memset(proto, 0, sizeof(struct proto));
    proto->info = reg_info;
    proto->id = proto_count;
    proto_count++;

    if (reg_info->number_class) {
        proto->number_class = proto_number_class_get(reg_info->number_class);
        if (!proto->number_class)
            goto err_proto;
    }

    int res = pthread_rwlock_init(&proto->expectation_lock, NULL);
    if (res) {
        pomlog(POMLOG_ERR "Error while initializing the proto_expectation rwlock : %s", pom_strerror(res));
        goto err_proto;
    }

    res = pthread_rwlock_init(&proto->listeners_lock, NULL);
    if (res) {
        pomlog(POMLOG_ERR "Error while initializing the proto_listeners rwlock : %s", pom_strerror(res));
        goto err_lock1;
    }

    proto->reg_instance = registry_add_instance(proto_registry_class, reg_info->name);
    if (!proto->reg_instance) {
        pomlog(POMLOG_ERR "Error while adding the registry instanc for protocol %s", reg_info->name);
        goto err_lock;
    }


    // Allocate the conntrack table
    if (reg_info->ct_info) {
        proto->ct = conntrack_table_alloc(reg_info->ct_info->default_table_size, (reg_info->ct_info->rev_pkt_field_id == -1 ? 0 : 1));
        if (!proto->ct) {
            pomlog(POMLOG_ERR "Error while allocating conntrack tables");
            goto err_registry;
        }

        proto->perf_conn_cur = registry_instance_add_perf(proto->reg_instance, "conn_cur", registry_perf_type_gauge, "Current number of monitored connection", "connections");
        proto->perf_conn_tot = registry_instance_add_perf(proto->reg_instance, "conn_tot", registry_perf_type_counter, "Total number of connections", "connections");
        proto->perf_conn_hash_col = registry_instance_add_perf(proto->reg_instance, "conn_hash_col", registry_perf_type_counter, "Total number of conntrack hash collisions", "collisions");

        if (!proto->perf_conn_cur || !proto->perf_conn_tot || !proto->perf_conn_hash_col)
            goto err_conntrack;

    }

    proto->perf_pkts = registry_instance_add_perf(proto->reg_instance, "pkts", registry_perf_type_counter, "Number of packets processed", "pkts");
    proto->perf_bytes = registry_instance_add_perf(proto->reg_instance, "bytes", registry_perf_type_counter, "Number of bytes processed", "bytes");
    proto->perf_expt_pending = registry_instance_add_perf(proto->reg_instance, "expectations_pending", registry_perf_type_gauge, "Number of expectations pending", "expectations");
    proto->perf_expt_matched = registry_instance_add_perf(proto->reg_instance, "expectations_matched", registry_perf_type_counter, "Number of expectations matched", "expectations");

    if (!proto->perf_pkts || !proto->perf_bytes || !proto->perf_expt_pending || !proto->perf_expt_matched)
        goto err_conntrack;

    if (reg_info->init) {
        if (reg_info->init(proto, proto->reg_instance) == POM_ERR) {
            pomlog(POMLOG_ERR "Error while registering proto %s", reg_info->name);
            goto err_conntrack;
        }
    }

    mod_refcount_inc(reg_info->mod);

    proto->next = proto_head;
    if (proto->next)
        proto->next->prev = proto;
    proto_head = proto;

    pomlog(POMLOG_DEBUG "Proto %s registered", reg_info->name);

    return POM_OK;

err_conntrack:
    // Remove proto number if any
    proto_number_unregister(proto);
    conntrack_table_cleanup(proto->ct);
err_registry:
    registry_remove_instance(proto->reg_instance);
err_lock:
    pthread_rwlock_destroy(&proto->listeners_lock);
err_lock1:
    pthread_rwlock_destroy(&proto->expectation_lock);
err_proto:
    free(proto);

    return POM_ERR;

}
Пример #30
0
int core_init(unsigned int num_threads) {

	core_registry_class = registry_add_class(CORE_REGISTRY);
	if (!core_registry_class)
		return POM_ERR;

	perf_pkt_queue = registry_class_add_perf(core_registry_class, "pkt_queue", registry_perf_type_gauge, "Number of packets in the queue waiting to be processed", "pkts");
	perf_thread_active = registry_class_add_perf(core_registry_class, "active_thread", registry_perf_type_gauge, "Number of active threads", "threads");

	if (!perf_pkt_queue || !perf_thread_active)
		return POM_OK;

	core_param_dump_pkt = ptype_alloc("bool");
	if (!core_param_dump_pkt)
		return POM_ERR;

	core_param_offline_dns = ptype_alloc("bool");
	if (!core_param_offline_dns) {
		ptype_cleanup(core_param_dump_pkt);
		core_param_dump_pkt = NULL;
		return POM_ERR;
	}

	core_param_reset_perf_on_restart = ptype_alloc("bool");
	if (!core_param_reset_perf_on_restart) {
		ptype_cleanup(core_param_dump_pkt);
		core_param_dump_pkt = NULL;
		ptype_cleanup(core_param_offline_dns);
		core_param_offline_dns = NULL;
		return POM_ERR;
	}

	struct registry_param *param = registry_new_param("dump_pkt", "no", core_param_dump_pkt, "Dump packets to logs", REGISTRY_PARAM_FLAG_CLEANUP_VAL);
	if (registry_class_add_param(core_registry_class, param) != POM_OK)
		goto err;

	param = registry_new_param("offline_dns", "yes", core_param_offline_dns, "Enable offline DNS resolver", REGISTRY_PARAM_FLAG_CLEANUP_VAL);
	if (registry_class_add_param(core_registry_class, param) != POM_OK)
		goto err;

	param = registry_new_param("reset_perf_on_restart", "no", core_param_reset_perf_on_restart, "Reset performances when core restarts", REGISTRY_PARAM_FLAG_CLEANUP_VAL);
	if (registry_class_add_param(core_registry_class, param) != POM_OK)
		goto err;
	
	param = NULL;

	// Start the processing threads
	unsigned int num_cpu = sysconf(_SC_NPROCESSORS_ONLN) - 1;
	if (num_cpu < 1) {
		pomlog(POMLOG_WARN "Could not find the number of CPU, assuming %u", CORE_PROCESS_THREAD_DEFAULT);
		num_cpu = CORE_PROCESS_THREAD_DEFAULT;
	}

	if (num_threads < 1)
		num_threads = num_cpu;

	if (num_threads > num_cpu)
		pomlog(POMLOG_WARN "WARNING : Running more processing threads than available CPU is discouraged as it will cause issues by creating higher latencies and eventually dropping packets !!! You have been warned !");

	if (num_threads > CORE_PROCESS_THREAD_MAX)
		num_threads = CORE_PROCESS_THREAD_MAX;

	core_num_threads = num_threads;	
	pomlog(POMLOG_INFO "Starting %u processing thread(s)", core_num_threads);

	core_run = 1;

	memset(core_processing_threads, 0, sizeof(struct core_processing_thread*) * CORE_PROCESS_THREAD_MAX);

	unsigned int i;

	for (i = 0; i < core_num_threads; i++) {
		struct core_processing_thread *tmp = malloc(sizeof(struct core_processing_thread));
		if (!tmp) {
			pom_oom(sizeof(struct core_processing_thread));
			goto err;
		}
		memset(tmp, 0, sizeof(struct core_processing_thread));

		tmp->thread_id = i;

		int res = pthread_mutex_init(&tmp->pkt_queue_lock, NULL);
		if (res) {
			pomlog(POMLOG_ERR "Error while initializing a thread pkt_queue lock : %s", pom_strerror(res));
			free(tmp);
			goto err;
		}

		res = pthread_cond_init(&tmp->pkt_queue_cond, NULL);
		if (res) {
			pomlog(POMLOG_ERR "Error while initializing a thread pkt_queue condition : %s", pom_strerror(res));
			pthread_mutex_destroy(&tmp->pkt_queue_lock);
			free(tmp);
			goto err;
		}


		if (pthread_create(&tmp->thread, NULL, core_processing_thread_func, tmp)) {
			pomlog(POMLOG_ERR "Error while creating a new processing thread : %s", pom_strerror(errno));
			pthread_mutex_destroy(&tmp->pkt_queue_lock);
			pthread_cond_destroy(&tmp->pkt_queue_cond);
			free(tmp);
			goto err;
		}


		core_processing_threads[i] = tmp;
	}

	return POM_OK;

err:

	if (param)
		registry_cleanup_param(param);

	core_cleanup(0);
	return POM_ERR;

}