diff options
author | Yves-Alexis Perez <corsac@debian.org> | 2013-08-25 15:37:26 +0200 |
---|---|---|
committer | Yves-Alexis Perez <corsac@debian.org> | 2013-08-25 15:37:26 +0200 |
commit | 6b99c8d9cff7b3e8ae8f3204b99e7ea40f791349 (patch) | |
tree | 009fc492961e13860d2a4bc2de8caf2bbe2975e7 /src/libfast/dispatcher.c | |
parent | c83921a2b566aa9d55d8ccc7258f04fca6292ee6 (diff) | |
download | vyos-strongswan-6b99c8d9cff7b3e8ae8f3204b99e7ea40f791349.tar.gz vyos-strongswan-6b99c8d9cff7b3e8ae8f3204b99e7ea40f791349.zip |
Imported Upstream version 5.1.0
Diffstat (limited to 'src/libfast/dispatcher.c')
-rw-r--r-- | src/libfast/dispatcher.c | 456 |
1 files changed, 0 insertions, 456 deletions
diff --git a/src/libfast/dispatcher.c b/src/libfast/dispatcher.c deleted file mode 100644 index e5a02c63b..000000000 --- a/src/libfast/dispatcher.c +++ /dev/null @@ -1,456 +0,0 @@ -/* - * Copyright (C) 2007 Martin Willi - * Hochschule fuer Technik Rapperswil - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - */ - -#include "dispatcher.h" - -#include "request.h" -#include "session.h" - -#include <fcgiapp.h> -#include <signal.h> -#include <unistd.h> - -#include <utils/debug.h> -#include <threading/thread.h> -#include <threading/condvar.h> -#include <threading/mutex.h> -#include <collections/linked_list.h> -#include <collections/hashtable.h> - -/** Intervall to check for expired sessions, in seconds */ -#define CLEANUP_INTERVAL 30 - -typedef struct private_dispatcher_t private_dispatcher_t; - -/** - * private data of the task manager - */ -struct private_dispatcher_t { - - /** - * public functions - */ - dispatcher_t public; - - /** - * fcgi socket fd - */ - int fd; - - /** - * thread list - */ - thread_t **threads; - - /** - * number of threads in "threads" - */ - int thread_count; - - /** - * session locking mutex - */ - mutex_t *mutex; - - /** - * Hahstable with active sessions - */ - hashtable_t *sessions; - - /** - * session timeout - */ - time_t timeout; - - /** - * timestamp of last session cleanup round - */ - time_t last_cleanup; - - /** - * running in debug mode? - */ - bool debug; - - /** - * List of controllers controller_constructor_t - */ - linked_list_t *controllers; - - /** - * List of filters filter_constructor_t - */ - linked_list_t *filters; - - /** - * constructor function to create session context (in controller_entry_t) - */ - context_constructor_t context_constructor; - - /** - * user param to context constructor - */ - void *param; -}; - -typedef struct { - /** constructor function */ - controller_constructor_t constructor; - /** parameter to constructor */ - void *param; -} controller_entry_t; - -typedef struct { - /** constructor function */ - filter_constructor_t constructor; - /** parameter to constructor */ - void *param; -} filter_entry_t; - -typedef struct { - /** session instance */ - session_t *session; - /** condvar to wait for session */ - condvar_t *cond; - /** client host address, to prevent session hijacking */ - char *host; - /** TRUE if session is in use */ - bool in_use; - /** last use of the session */ - time_t used; - /** has the session been closed by the handler? */ - bool closed; -} session_entry_t; - -/** - * create a session and instanciate controllers - */ -static session_t* load_session(private_dispatcher_t *this) -{ - enumerator_t *enumerator; - controller_entry_t *centry; - filter_entry_t *fentry; - session_t *session; - context_t *context = NULL; - controller_t *controller; - filter_t *filter; - - if (this->context_constructor) - { - context = this->context_constructor(this->param); - } - session = session_create(context); - - enumerator = this->controllers->create_enumerator(this->controllers); - while (enumerator->enumerate(enumerator, ¢ry)) - { - controller = centry->constructor(context, centry->param); - session->add_controller(session, controller); - } - enumerator->destroy(enumerator); - - enumerator = this->filters->create_enumerator(this->filters); - while (enumerator->enumerate(enumerator, &fentry)) - { - filter = fentry->constructor(context, fentry->param); - session->add_filter(session, filter); - } - enumerator->destroy(enumerator); - - return session; -} - -/** - * create a new session entry - */ -static session_entry_t *session_entry_create(private_dispatcher_t *this, - char *host) -{ - session_entry_t *entry; - session_t *session; - - session = load_session(this); - if (!session) - { - return NULL; - } - INIT(entry, - .cond = condvar_create(CONDVAR_TYPE_DEFAULT), - .session = session, - .host = strdup(host), - .used = time_monotonic(NULL), - ); - return entry; -} - -/** - * destroy a session - */ -static void session_entry_destroy(session_entry_t *entry) -{ - entry->session->destroy(entry->session); - entry->cond->destroy(entry->cond); - free(entry->host); - free(entry); -} - -METHOD(dispatcher_t, add_controller, void, - private_dispatcher_t *this, controller_constructor_t constructor, - void *param) -{ - controller_entry_t *entry; - - INIT(entry, - .constructor = constructor, - .param = param, - ); - this->controllers->insert_last(this->controllers, entry); -} - -METHOD(dispatcher_t, add_filter, void, - private_dispatcher_t *this, filter_constructor_t constructor, void *param) -{ - filter_entry_t *entry; - - INIT(entry, - .constructor = constructor, - .param = param, - ); - this->filters->insert_last(this->filters, entry); -} - -/** - * Hashtable hash function - */ -static u_int session_hash(char *sid) -{ - return chunk_hash(chunk_create(sid, strlen(sid))); -} - -/** - * Hashtable equals function - */ -static bool session_equals(char *sid1, char *sid2) -{ - return streq(sid1, sid2); -} - -/** - * Cleanup unused sessions - */ -static void cleanup_sessions(private_dispatcher_t *this, time_t now) -{ - if (this->last_cleanup < now - CLEANUP_INTERVAL) - { - char *sid; - session_entry_t *entry; - enumerator_t *enumerator; - linked_list_t *remove; - - this->last_cleanup = now; - remove = linked_list_create(); - enumerator = this->sessions->create_enumerator(this->sessions); - while (enumerator->enumerate(enumerator, &sid, &entry)) - { - /* check all sessions for timeout or close flag */ - if (!entry->in_use && - (entry->used < now - this->timeout || entry->closed)) - { - remove->insert_last(remove, sid); - } - } - enumerator->destroy(enumerator); - - while (remove->remove_last(remove, (void**)&sid) == SUCCESS) - { - entry = this->sessions->remove(this->sessions, sid); - if (entry) - { - session_entry_destroy(entry); - } - } - remove->destroy(remove); - } -} - -/** - * Actual dispatching code - */ -static void dispatch(private_dispatcher_t *this) -{ - thread_cancelability(FALSE); - - while (TRUE) - { - request_t *request; - session_entry_t *found = NULL; - time_t now; - char *sid; - - thread_cancelability(TRUE); - request = request_create(this->fd, this->debug); - thread_cancelability(FALSE); - - if (request == NULL) - { - continue; - } - now = time_monotonic(NULL); - sid = request->get_cookie(request, "SID"); - - this->mutex->lock(this->mutex); - if (sid) - { - found = this->sessions->get(this->sessions, sid); - } - if (found && !streq(found->host, request->get_host(request))) - { - found = NULL; - } - if (found) - { - /* wait until session is unused */ - while (found->in_use) - { - found->cond->wait(found->cond, this->mutex); - } - } - else - { /* create a new session if not found */ - found = session_entry_create(this, request->get_host(request)); - if (!found) - { - request->destroy(request); - this->mutex->unlock(this->mutex); - continue; - } - sid = found->session->get_sid(found->session); - this->sessions->put(this->sessions, sid, found); - } - found->in_use = TRUE; - this->mutex->unlock(this->mutex); - - /* start processing */ - found->session->process(found->session, request); - found->used = time_monotonic(NULL); - - /* release session */ - this->mutex->lock(this->mutex); - found->in_use = FALSE; - found->closed = request->session_closed(request); - found->cond->signal(found->cond); - cleanup_sessions(this, now); - this->mutex->unlock(this->mutex); - - request->destroy(request); - } -} - -METHOD(dispatcher_t, run, void, - private_dispatcher_t *this, int threads) -{ - this->thread_count = threads; - this->threads = malloc(sizeof(thread_t*) * threads); - while (threads) - { - this->threads[threads - 1] = thread_create((thread_main_t)dispatch, - this); - if (this->threads[threads - 1]) - { - threads--; - } - } -} - -METHOD(dispatcher_t, waitsignal, void, - private_dispatcher_t *this) -{ - sigset_t set; - int sig; - - sigemptyset(&set); - sigaddset(&set, SIGINT); - sigaddset(&set, SIGTERM); - sigaddset(&set, SIGHUP); - sigprocmask(SIG_BLOCK, &set, NULL); - sigwait(&set, &sig); -} - -METHOD(dispatcher_t, destroy, void, - private_dispatcher_t *this) -{ - char *sid; - session_entry_t *entry; - enumerator_t *enumerator; - - FCGX_ShutdownPending(); - while (this->thread_count--) - { - thread_t *thread = this->threads[this->thread_count]; - thread->cancel(thread); - thread->join(thread); - } - enumerator = this->sessions->create_enumerator(this->sessions); - while (enumerator->enumerate(enumerator, &sid, &entry)) - { - session_entry_destroy(entry); - } - enumerator->destroy(enumerator); - this->sessions->destroy(this->sessions); - this->controllers->destroy_function(this->controllers, free); - this->filters->destroy_function(this->filters, free); - this->mutex->destroy(this->mutex); - free(this->threads); - free(this); -} - -/* - * see header file - */ -dispatcher_t *dispatcher_create(char *socket, bool debug, int timeout, - context_constructor_t constructor, void *param) -{ - private_dispatcher_t *this; - - INIT(this, - .public = { - .add_controller = _add_controller, - .add_filter = _add_filter, - .run = _run, - .waitsignal = _waitsignal, - .destroy = _destroy, - }, - .sessions = hashtable_create((void*)session_hash, - (void*)session_equals, 4096), - .controllers = linked_list_create(), - .filters = linked_list_create(), - .context_constructor = constructor, - .mutex = mutex_create(MUTEX_TYPE_DEFAULT), - .param = param, - .timeout = timeout, - .last_cleanup = time_monotonic(NULL), - .debug = debug, - ); - - FCGX_Init(); - - if (socket) - { - unlink(socket); - this->fd = FCGX_OpenSocket(socket, 10); - } - return &this->public; -} - |