moved initiate() code to the generic controller_t class

This commit is contained in:
Martin Willi
2007-04-16 12:52:49 +00:00
parent 418dbd6243
commit 217e985b41
5 changed files with 224 additions and 68 deletions
+134
View File
@@ -0,0 +1,134 @@
/**
* @file controller.c
*
* @brief Implementation of controller_t.
*
*/
/*
* 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 "controller.h"
#include <daemon.h>
#include <library.h>
#include <processing/job_queue.h>
#include <processing/jobs/initiate_job.h>
typedef struct private_controller_t private_controller_t;
/**
* Private data of an stroke_t object.
*/
struct private_controller_t {
/**
* Public part of stroke_t object.
*/
controller_t public;
};
/**
* Implementation of controller_t.initiate.
*/
static status_t initiate(private_controller_t *this,
peer_cfg_t *peer_cfg, child_cfg_t *child_cfg,
bool(*cb)(void*,signal_t,level_t,ike_sa_t*,char*,va_list),
void *param)
{
ike_sa_t *ours = NULL;
job_t *job;
status_t retval;
charon->bus->set_listen_state(charon->bus, TRUE);
job = (job_t*)initiate_job_create(peer_cfg, child_cfg);
charon->job_queue->add(charon->job_queue, job);
while (TRUE)
{
level_t level;
signal_t signal;
int thread;
ike_sa_t *ike_sa;
char* format;
va_list args;
signal = charon->bus->listen(charon->bus, &level, &thread,
&ike_sa, &format, &args);
if (ike_sa == ours || ours == NULL)
{
if (!cb(param, signal, level, ike_sa, format, args))
{
charon->bus->set_listen_state(charon->bus, FALSE);
return NEED_MORE;
}
}
switch (signal)
{
case CHILD_UP_SUCCESS:
if (ike_sa == ours)
{
retval = SUCCESS;
break;
}
continue;
case CHILD_UP_FAILED:
case IKE_UP_FAILED:
if (ike_sa == ours)
{
retval = FAILED;
break;
}
continue;
case CHILD_UP_START:
case IKE_UP_START:
if (ours == NULL)
{
ours = ike_sa;
}
continue;
default:
continue;
}
break;
}
charon->bus->set_listen_state(charon->bus, FALSE);
return retval;
}
/**
* Implementation of stroke_t.destroy.
*/
static void destroy(private_controller_t *this)
{
free(this);
}
/*
* Described in header-file
*/
controller_t *controller_create(void)
{
private_controller_t *this = malloc_thing(private_controller_t);
this->public.initiate = (status_t(*)(controller_t*,peer_cfg_t*,child_cfg_t*,bool(*)(void*,signal_t,level_t,ike_sa_t*,char*,va_list),void*))initiate;
this->public.destroy = (void (*)(controller_t*))destroy;
return &this->public;
}
+38 -9
View File
@@ -23,18 +23,30 @@
#ifndef CONTROLLER_H_ #ifndef CONTROLLER_H_
#define CONTROLLER_H_ #define CONTROLLER_H_
typedef struct controller_t controller_t; #include <bus/bus.h>
#include <config/backends/local_backend.h>
/** /**
* @brief controller is a configuration and control interface which * callback to log things triggered by controller
* allows other processes to modify charons behavior.
* *
* controller_t allows config manipulation (as whack in pluto). Configurations * @param param echoed parameter supplied when function invoked
* are stored in a special backend, the in-memory local_backend_t. * @param signal type of signal
* Messages of type controller_msg_t's are sent over a unix socket * @param level verbosity level if log
* (/var/run/charon.ctl). * @param ike_sa associated IKE_SA, if any
* @param format printf like format string
* @param args list of arguments to use for format
* @return FALSE to return from invoked function
* @ingroup control
*/
typedef bool(*controller_cb_t)(void* param, signal_t signal, level_t level,
ike_sa_t* ike_sa, char* format, va_list args);
typedef struct controller_t controller_t;
/**
* @brief The controller controls the daemon.
*
* The controller starts actions by creating jobs. It then tries to
* evaluate the result of the operation by listening on the bus.
* *
* @b Constructors: * @b Constructors:
* - controller_create() * - controller_create()
@@ -43,6 +55,23 @@ typedef struct controller_t controller_t;
*/ */
struct controller_t { struct controller_t {
/**
* @brief Initiate a CHILD_SA, and if required, an IKE_SA.
*
* @param this calling object
* @param peer_cfg peer_cfg to use for IKE_SA setup
* @param child_cfg child_cfg to set up CHILD_SA from
* @param cb logging callback
* @param param parameter to include in each call of cb
* @return
* - SUCCESS, if CHILD_SA established
* - FAILED, if setup failed
* - NEED_MORE, if callback returned FALSE
*/
status_t (*initiate)(controller_t *this,
peer_cfg_t *peer_cfg, child_cfg_t *child_cfg,
controller_cb_t callback, void *param);
/** /**
* @brief Destroy a controller_t instance. * @brief Destroy a controller_t instance.
* *
+41 -57
View File
@@ -40,6 +40,7 @@
#include <crypto/x509.h> #include <crypto/x509.h>
#include <crypto/ca.h> #include <crypto/ca.h>
#include <crypto/crl.h> #include <crypto/crl.h>
#include <control/controller.h>
#include <processing/jobs/initiate_job.h> #include <processing/jobs/initiate_job.h>
#include <processing/jobs/route_job.h> #include <processing/jobs/route_job.h>
#include <utils/leak_detective.h> #include <utils/leak_detective.h>
@@ -79,6 +80,24 @@ struct private_stroke_interface_t {
pthread_t threads[STROKE_THREADS]; pthread_t threads[STROKE_THREADS];
}; };
typedef struct stroke_log_info_t stroke_log_info_t;
/**
* helper struct to say what and where to log when using controller callback
*/
struct stroke_log_info_t {
/**
* level to log up to
*/
level_t level;
/**
* where to write log
*/
FILE* out;
};
/** /**
* Helper function which corrects the string pointers * Helper function which corrects the string pointers
* in a stroke_msg_t. Strings in a stroke_msg sent over "wire" * in a stroke_msg_t. Strings in a stroke_msg sent over "wire"
@@ -638,17 +657,30 @@ static child_cfg_t* get_child_from_peer(peer_cfg_t *peer_cfg, char *name)
return found; return found;
} }
/**
* logging to the stroke interface
*/
static bool stroke_log(stroke_log_info_t *info, signal_t signal, level_t level,
ike_sa_t *ike_sa, char *format, va_list args)
{
if (level <= info->level)
{
vfprintf(info->out, format, args);
fprintf(info->out, "\n");
fflush(info->out);
}
return TRUE;
}
/** /**
* initiate a connection by name * initiate a connection by name
*/ */
static void stroke_initiate(private_stroke_interface_t *this, static void stroke_initiate(private_stroke_interface_t *this,
stroke_msg_t *msg, FILE *out) stroke_msg_t *msg, FILE *out)
{ {
initiate_job_t *job;
peer_cfg_t *peer_cfg; peer_cfg_t *peer_cfg;
child_cfg_t *child_cfg; child_cfg_t *child_cfg;
ike_sa_t *init_ike_sa = NULL; stroke_log_info_t info;
signal_t signal;
pop_string(msg, &(msg->initiate.name)); pop_string(msg, &(msg->initiate.name));
DBG1(DBG_CFG, "received stroke: initiate '%s'", msg->initiate.name); DBG1(DBG_CFG, "received stroke: initiate '%s'", msg->initiate.name);
@@ -657,10 +689,7 @@ static void stroke_initiate(private_stroke_interface_t *this,
msg->initiate.name); msg->initiate.name);
if (peer_cfg == NULL) if (peer_cfg == NULL)
{ {
if (msg->output_verbosity >= 0) fprintf(out, "no config named '%s'\n", msg->initiate.name);
{
fprintf(out, "no config named '%s'\n", msg->initiate.name);
}
return; return;
} }
if (peer_cfg->get_ike_version(peer_cfg) != 2) if (peer_cfg->get_ike_version(peer_cfg) != 2)
@@ -674,61 +703,16 @@ static void stroke_initiate(private_stroke_interface_t *this,
child_cfg = get_child_from_peer(peer_cfg, msg->initiate.name); child_cfg = get_child_from_peer(peer_cfg, msg->initiate.name);
if (child_cfg == NULL) if (child_cfg == NULL)
{ {
if (msg->output_verbosity >= 0) fprintf(out, "no child config named '%s'\n", msg->initiate.name);
{
fprintf(out, "no child config named '%s'\n", msg->initiate.name);
}
peer_cfg->destroy(peer_cfg); peer_cfg->destroy(peer_cfg);
return; return;
} }
job = initiate_job_create(peer_cfg, child_cfg); info.out = out;
charon->bus->set_listen_state(charon->bus, TRUE); info.level = msg->output_verbosity;
charon->job_queue->add(charon->job_queue, (job_t*)job);
while (TRUE)
{
level_t level;
int thread;
ike_sa_t *ike_sa;
char* format;
va_list args;
signal = charon->bus->listen(charon->bus, &level, &thread, &ike_sa, &format, &args); charon->controller->initiate(charon->controller, peer_cfg, child_cfg,
(controller_cb_t)stroke_log, &info);
if ((init_ike_sa == NULL || ike_sa == init_ike_sa) &&
level <= msg->output_verbosity)
{
if (vfprintf(out, format, args) < 0 ||
fprintf(out, "\n") < 0 ||
fflush(out))
{
charon->bus->set_listen_state(charon->bus, FALSE);
break;
}
}
switch (signal)
{
case CHILD_UP_SUCCESS:
case CHILD_UP_FAILED:
case IKE_UP_FAILED:
if (ike_sa == init_ike_sa)
{
charon->bus->set_listen_state(charon->bus, FALSE);
return;
}
continue;
case CHILD_UP_START:
case IKE_UP_START:
if (init_ike_sa == NULL)
{
init_ike_sa = ike_sa;
}
continue;
default:
continue;
}
}
} }
/** /**
+3
View File
@@ -165,6 +165,7 @@ static void destroy(private_daemon_t *this)
DESTROY_IF(this->public.receiver); DESTROY_IF(this->public.receiver);
/* ignore all incoming user requests */ /* ignore all incoming user requests */
DESTROY_IF(this->public.stroke); DESTROY_IF(this->public.stroke);
DESTROY_IF(this->public.controller);
/* stop scheduing jobs */ /* stop scheduing jobs */
DESTROY_IF(this->public.scheduler); DESTROY_IF(this->public.scheduler);
/* stop processing jobs */ /* stop processing jobs */
@@ -280,6 +281,7 @@ static void initialize(private_daemon_t *this, bool strict, bool syslog,
credentials->load_secrets(credentials); credentials->load_secrets(credentials);
/* start building threads, we are multi-threaded NOW */ /* start building threads, we are multi-threaded NOW */
this->public.controller = controller_create();
this->public.stroke = stroke_create(this->public.local_backend); this->public.stroke = stroke_create(this->public.local_backend);
this->public.sender = sender_create(); this->public.sender = sender_create();
this->public.receiver = receiver_create(); this->public.receiver = receiver_create();
@@ -342,6 +344,7 @@ private_daemon_t *daemon_create(void)
this->public.scheduler = NULL; this->public.scheduler = NULL;
this->public.kernel_interface = NULL; this->public.kernel_interface = NULL;
this->public.thread_pool = NULL; this->public.thread_pool = NULL;
this->public.controller = NULL;
this->public.stroke = NULL; this->public.stroke = NULL;
this->public.bus = NULL; this->public.bus = NULL;
this->public.outlog = NULL; this->public.outlog = NULL;
+6
View File
@@ -37,6 +37,7 @@ typedef struct daemon_t daemon_t;
#include <processing/job_queue.h> #include <processing/job_queue.h>
#include <processing/event_queue.h> #include <processing/event_queue.h>
#include <kernel/kernel_interface.h> #include <kernel/kernel_interface.h>
#include <control/controller.h>
#include <control/stroke_interface.h> #include <control/stroke_interface.h>
#include <bus/bus.h> #include <bus/bus.h>
#include <bus/listeners/file_logger.h> #include <bus/listeners/file_logger.h>
@@ -411,6 +412,11 @@ struct daemon_t {
*/ */
kernel_interface_t *kernel_interface; kernel_interface_t *kernel_interface;
/**
* control the daemon
*/
controller_t *controller;;
/** /**
* IPC interface, as whack in pluto * IPC interface, as whack in pluto
*/ */