예제 #1
0
파일: proto.c 프로젝트: nomnom100/pom-ng
void proto_expectation_cleanup(struct proto_expectation *e) {

    if (!e)
        return;

    debug_expectation("Cleaning up expectation %p", e);

    while (e->head) {
        struct proto_expectation_stack *es = e->head;
        e->head = es->next;
        if (es->fields[POM_DIR_FWD])
            ptype_cleanup(es->fields[POM_DIR_FWD]);
        if (es->fields[POM_DIR_REV])
            ptype_cleanup(es->fields[POM_DIR_REV]);

        free(es);

    }

    if (e->session)
        conntrack_session_refcount_dec(e->session);

    timer_cleanup(e->expiry);

    free(e);
}
예제 #2
0
파일: conntrack.c 프로젝트: elfixit/pom-ng
int conntrack_session_bind(struct conntrack_entry *ce, struct conntrack_session *session) {

	if (ce->session) {
		pomlog(POMLOG_WARN "Warning, session already exists when trying to bind another session. TODO: implement merging");
		conntrack_session_refcount_dec(ce->session);
	}

	conntrack_session_refcount_inc(session);
	ce->session = session;

	return POM_OK;
}
예제 #3
0
void proto_expectation_cleanup(struct proto_expectation *e) {

	if (!e)
		return;

	if (e->flags & PROTO_EXPECTATION_FLAG_QUEUED)
		proto_expectation_remove(e);

	debug_expectation("Cleaning up expectation %p", e);

	while (e->head) {
		struct proto_expectation_stack *es = e->head;
		e->head = es->next;
		if (es->fields[POM_DIR_FWD])
			ptype_cleanup(es->fields[POM_DIR_FWD]);
		if (es->fields[POM_DIR_REV])
			ptype_cleanup(es->fields[POM_DIR_REV]);
		
		free(es);

	}

	if (e->priv && e->proto->info->ct_info->cleanup_handler) {
		if (e->proto->info->ct_info->cleanup_handler(e->priv) != POM_OK)
			pomlog(POMLOG_WARN "Unable to free the conntrack priv of the proto_expectation");
	}

	if (e->session)
		conntrack_session_refcount_dec(e->session);

	if (e->expiry)
		timer_cleanup(e->expiry);

	if (e->callback_priv && e->callback_priv_cleanup)
		e->callback_priv_cleanup(e->callback_priv);

	free(e);
}
예제 #4
0
파일: conntrack.c 프로젝트: elfixit/pom-ng
int conntrack_cleanup(struct conntrack_tables *ct, uint32_t hash, struct conntrack_entry *ce) {

	// Remove the conntrack from the conntrack table
	pom_mutex_lock(&ct->locks[hash]);

	// Try to find the conntrack in the list
	struct conntrack_list *lst = NULL;

	for (lst = ct->table[hash]; lst && lst->ce != ce; lst = lst->next);

	if (!lst) {
		pom_mutex_unlock(&ct->locks[hash]);
		pomlog(POMLOG_ERR "Trying to cleanup a non existing conntrack : %p", ce);
		return POM_OK;
	}

	conntrack_lock(ce);
	if (ce->refcount) {
		debug_conntrack(POMLOG_ERR "Conntrack %p is still being referenced : %u !", ce, ce->refcount);
		conntrack_delayed_cleanup(ce, 1, core_get_clock_last());
		conntrack_unlock(ce);
		pom_mutex_unlock(&ct->locks[hash]);
		return POM_OK;
	}


	if (lst->prev)
		lst->prev->next = lst->next;
	else
		ct->table[hash] = lst->next;

	if (lst->next)
		lst->next->prev = lst->prev;

	free(lst);

	pom_mutex_unlock(&ct->locks[hash]);

	if (ce->cleanup_timer && ce->cleanup_timer != (void *) -1) {
		conntrack_timer_cleanup(ce->cleanup_timer);
		ce->cleanup_timer = (void *) -1; // Mark that the conntrack is being cleaned up
	}

	// Once the conntrack is removed from the hash table, it will not be referenced ever again
	conntrack_unlock(ce);

	if (ce->parent) {
		debug_conntrack("Cleaning up conntrack %p, with parent %p", ce, ce->parent->ce);
	} else {
		debug_conntrack("Cleaning up conntrack %p, with no parent", ce);
	}

	
	if (ce->parent) {
		// Remove the child from the parent
		
		// Make sure the parent still exists
		uint32_t hash = ce->parent->hash;
		pom_mutex_lock(&ce->parent->ct->locks[hash]);
		
		for (lst = ce->parent->ct->table[hash]; lst && lst->ce != ce->parent->ce; lst = lst->next);

		if (lst) {

			conntrack_lock(ce->parent->ce);
			struct conntrack_node_list *tmp = ce->parent->ce->children;

			for (; tmp && tmp->ce != ce; tmp = tmp->next);

			if (tmp) {
				if (tmp->prev)
					tmp->prev->next = tmp->next;
				else
					ce->parent->ce->children = tmp->next;

				if (tmp->next)
					tmp->next->prev = tmp->prev;

				free(tmp);
			} else {
				pomlog(POMLOG_WARN "Conntrack %s not found in parent's %s children list", ce, ce->parent->ce);
			}

			if (!ce->parent->ce->children) // Parent has no child anymore, clean it up after some time
				conntrack_delayed_cleanup(ce->parent->ce, CONNTRACK_CHILDLESS_TIMEOUT, core_get_clock_last());

			conntrack_unlock(ce->parent->ce);
		} else {
			debug_conntrack("Parent conntrack %p not found while cleaning child %p !", ce->parent->ce, ce);
		}

		pom_mutex_unlock(&ce->parent->ct->locks[hash]);

		free(ce->parent);
	}

	if (ce->session)
		conntrack_session_refcount_dec(ce->session);

	// Cleanup private stuff from the conntrack
	if (ce->priv && ce->proto->info->ct_info->cleanup_handler) {
		if (ce->proto->info->ct_info->cleanup_handler(ce->priv) != POM_OK)
			pomlog(POMLOG_WARN "Unable to free the private memory of a conntrack");
	}

	// Cleanup the priv_list
	struct conntrack_priv_list *priv_lst = ce->priv_list;
	while (priv_lst) {
		if (priv_lst->cleanup) {
			if (priv_lst->cleanup(priv_lst->obj, priv_lst->priv) != POM_OK)
				pomlog(POMLOG_WARN "Error while cleaning up private objects in conntrack_entry");
		}
		ce->priv_list = priv_lst->next;
		free(priv_lst);
		priv_lst = ce->priv_list;

	}


	// Cleanup the children
	while (ce->children) {
		struct conntrack_node_list *child = ce->children;
		ce->children = child->next;

		if (conntrack_cleanup(child->ct, child->hash, child->ce) != POM_OK) 
			return POM_ERR;

		free(child);
	}

	
	if (ce->fwd_value)
		ptype_cleanup(ce->fwd_value);
	if (ce->rev_value)
		ptype_cleanup(ce->rev_value);

	pthread_mutex_destroy(&ce->lock);

	registry_perf_dec(ce->proto->perf_conn_cur, 1);

	free(ce);

	return POM_OK;
}