restructuring of configuration backends
added propotypes of new control interfaces (xml & dbus) introduced loadable: configuration backends control interfaces using pluggable modules as in EAP
This commit is contained in:
@@ -0,0 +1,244 @@
|
||||
/**
|
||||
* @file backend_manager.c
|
||||
*
|
||||
* @brief Implementation of backend_manager_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 "backend_manager.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <dirent.h>
|
||||
#include <sys/stat.h>
|
||||
#include <dlfcn.h>
|
||||
|
||||
#include <daemon.h>
|
||||
#include <utils/linked_list.h>
|
||||
#include <config/backends/writeable_backend.h>
|
||||
|
||||
|
||||
typedef struct private_backend_manager_t private_backend_manager_t;
|
||||
|
||||
/**
|
||||
* Private data of an backend_manager_t object.
|
||||
*/
|
||||
struct private_backend_manager_t {
|
||||
|
||||
/**
|
||||
* Public part of backend_manager_t object.
|
||||
*/
|
||||
backend_manager_t public;
|
||||
|
||||
/**
|
||||
* list of registered backends
|
||||
*/
|
||||
linked_list_t *backends;
|
||||
|
||||
/**
|
||||
* Additional list of writable backends.
|
||||
*/
|
||||
linked_list_t *writeable;
|
||||
|
||||
/**
|
||||
* List of dlopen() handles we used to open backends
|
||||
*/
|
||||
linked_list_t *handles;
|
||||
};
|
||||
|
||||
/**
|
||||
* implements backend_manager_t.get_ike_cfg.
|
||||
*/
|
||||
static ike_cfg_t *get_ike_cfg(private_backend_manager_t *this,
|
||||
host_t *my_host, host_t *other_host)
|
||||
{
|
||||
backend_t *backend;
|
||||
ike_cfg_t *config = NULL;
|
||||
iterator_t *iterator = this->backends->create_iterator(this->backends, TRUE);
|
||||
while (config == NULL && iterator->iterate(iterator, (void**)&backend))
|
||||
{
|
||||
config = backend->get_ike_cfg(backend, my_host, other_host);
|
||||
}
|
||||
iterator->destroy(iterator);
|
||||
return config;
|
||||
}
|
||||
|
||||
/**
|
||||
* implements backend_manager_t.get_peer_cfg.
|
||||
*/
|
||||
static peer_cfg_t *get_peer_cfg(private_backend_manager_t *this,
|
||||
identification_t *my_id, identification_t *other_id,
|
||||
identification_t *other_ca, char *other_group,
|
||||
host_t *my_host, host_t *other_host)
|
||||
{
|
||||
backend_t *backend;
|
||||
peer_cfg_t *config = NULL;
|
||||
iterator_t *iterator = this->backends->create_iterator(this->backends, TRUE);
|
||||
while (config == NULL && iterator->iterate(iterator, (void**)&backend))
|
||||
{
|
||||
config = backend->get_peer_cfg(backend, my_id, other_id, other_ca,
|
||||
other_group, my_host, other_host);
|
||||
}
|
||||
iterator->destroy(iterator);
|
||||
return config;
|
||||
}
|
||||
|
||||
/**
|
||||
* implements backend_manager_t.add_peer_cfg.
|
||||
*/
|
||||
static void add_peer_cfg(private_backend_manager_t *this, peer_cfg_t *config)
|
||||
{
|
||||
writeable_backend_t *backend;
|
||||
|
||||
if (this->writeable->get_first(this->writeable, (void**)&backend) == SUCCESS)
|
||||
{
|
||||
backend->add_cfg(backend, config);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* implements backend_manager_t.create_iterator.
|
||||
*/
|
||||
static iterator_t* create_iterator(private_backend_manager_t *this)
|
||||
{
|
||||
writeable_backend_t *backend;
|
||||
|
||||
if (this->writeable->get_first(this->writeable, (void**)&backend) == SUCCESS)
|
||||
{
|
||||
return backend->create_iterator(backend);
|
||||
}
|
||||
/* give out an empty iterator if we have no writable backend*/
|
||||
return this->writeable->create_iterator(this->writeable, TRUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* load the configuration backend modules
|
||||
*/
|
||||
static void load_backends(private_backend_manager_t *this)
|
||||
{
|
||||
struct dirent* entry;
|
||||
struct stat stb;
|
||||
DIR* dir;
|
||||
|
||||
if (stat(IPSEC_BACKENDDIR, &stb) == -1 || !(stb.st_mode & S_IFDIR))
|
||||
{
|
||||
DBG1(DBG_CFG, "error opening backend modules directory "IPSEC_BACKENDDIR);
|
||||
return;
|
||||
}
|
||||
|
||||
dir = opendir(IPSEC_BACKENDDIR);
|
||||
if (dir == NULL)
|
||||
{
|
||||
DBG1(DBG_CFG, "error opening backend modules directory "IPSEC_BACKENDDIR);
|
||||
return;
|
||||
}
|
||||
|
||||
DBG1(DBG_CFG, "loading backend modules from '"IPSEC_BACKENDDIR"'");
|
||||
|
||||
while ((entry = readdir(dir)) != NULL)
|
||||
{
|
||||
char file[256];
|
||||
backend_t *backend;
|
||||
backend_constructor_t constructor;
|
||||
void *handle;
|
||||
char *ending;
|
||||
|
||||
snprintf(file, sizeof(file), IPSEC_BACKENDDIR"/%s", entry->d_name);
|
||||
|
||||
if (stat(file, &stb) == -1 || !(stb.st_mode & S_IFREG))
|
||||
{
|
||||
DBG2(DBG_CFG, " skipping %s, doesn't look like a file",
|
||||
entry->d_name);
|
||||
continue;
|
||||
}
|
||||
ending = entry->d_name + strlen(entry->d_name) - 3;
|
||||
if (ending <= entry->d_name || !streq(ending, ".so"))
|
||||
{
|
||||
/* skip anything which does not look like a library */
|
||||
DBG2(DBG_CFG, " skipping %s, doesn't look like a library",
|
||||
entry->d_name);
|
||||
continue;
|
||||
}
|
||||
/* try to load the library */
|
||||
handle = dlopen(file, RTLD_LAZY);
|
||||
if (handle == NULL)
|
||||
{
|
||||
DBG1(DBG_CFG, " opening backend module %s failed: %s",
|
||||
entry->d_name, dlerror());
|
||||
continue;
|
||||
}
|
||||
constructor = dlsym(handle, "backend_create");
|
||||
if (constructor == NULL)
|
||||
{
|
||||
DBG1(DBG_CFG, " backend module %s has no backend_create() "
|
||||
"function, skipped", entry->d_name);
|
||||
dlclose(handle);
|
||||
continue;
|
||||
}
|
||||
|
||||
backend = constructor();
|
||||
if (backend == NULL)
|
||||
{
|
||||
DBG1(DBG_CFG, " unable to create instance of backend "
|
||||
"module %s, skipped", entry->d_name);
|
||||
dlclose(handle);
|
||||
continue;
|
||||
}
|
||||
DBG1(DBG_CFG, " loaded backend module successfully from %s", entry->d_name);
|
||||
this->backends->insert_last(this->backends, backend);
|
||||
if (backend->is_writeable(backend))
|
||||
{
|
||||
this->writeable->insert_last(this->writeable, backend);
|
||||
}
|
||||
this->handles->insert_last(this->handles, handle);
|
||||
}
|
||||
closedir(dir);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of backend_manager_t.destroy.
|
||||
*/
|
||||
static void destroy(private_backend_manager_t *this)
|
||||
{
|
||||
this->backends->destroy_offset(this->backends, offsetof(backend_t, destroy));
|
||||
this->writeable->destroy(this->writeable);
|
||||
this->handles->destroy_function(this->handles, (void*)dlclose);
|
||||
free(this);
|
||||
}
|
||||
|
||||
/*
|
||||
* Described in header-file
|
||||
*/
|
||||
backend_manager_t *backend_manager_create()
|
||||
{
|
||||
private_backend_manager_t *this = malloc_thing(private_backend_manager_t);
|
||||
|
||||
this->public.get_ike_cfg = (ike_cfg_t*(*)(backend_manager_t*, host_t *, host_t *))get_ike_cfg;
|
||||
this->public.get_peer_cfg = (peer_cfg_t*(*)(backend_manager_t*, identification_t *, identification_t *))get_peer_cfg;
|
||||
this->public.add_peer_cfg = (void(*)(backend_manager_t*, peer_cfg_t*))add_peer_cfg;
|
||||
this->public.create_iterator = (iterator_t*(*)(backend_manager_t*))create_iterator;
|
||||
this->public.destroy = (void(*)(backend_manager_t*))destroy;
|
||||
|
||||
this->backends = linked_list_create();
|
||||
this->writeable = linked_list_create();
|
||||
this->handles = linked_list_create();
|
||||
|
||||
load_backends(this);
|
||||
|
||||
return &this->public;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/**
|
||||
* @file cfg_store.h
|
||||
* @file backend_manager.h
|
||||
*
|
||||
* @brief Interface cfg_store_t.
|
||||
* @brief Interface backend_manager_t.
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -20,10 +20,10 @@
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#ifndef CFG_STORE_H_
|
||||
#define CFG_STORE_H_
|
||||
#ifndef BACKEND_MANAGER_H_
|
||||
#define BACKEND_MANAGER_H_
|
||||
|
||||
typedef struct cfg_store_t cfg_store_t;
|
||||
typedef struct backend_manager_t backend_manager_t;
|
||||
|
||||
#include <library.h>
|
||||
#include <utils/host.h>
|
||||
@@ -34,9 +34,9 @@ typedef struct cfg_store_t cfg_store_t;
|
||||
|
||||
|
||||
/**
|
||||
* @brief A multiplexer to use multiple cfg_store backends.
|
||||
* @brief A multiplexer to use multiple backends.
|
||||
*
|
||||
* Charon allows the use of multiple cfg_store backends simultaneously. To
|
||||
* Charon allows the use of multiple backend_manager backends simultaneously. To
|
||||
* access all this backends by a single call, this class wraps multiple
|
||||
* backends behind a single object.
|
||||
* Backends may be registered and unregister at runtime dynamically.
|
||||
@@ -44,22 +44,20 @@ typedef struct cfg_store_t cfg_store_t;
|
||||
|
||||
+---------+ +-----------+ +--------------+ |
|
||||
| | | | +--------------+ | |
|
||||
| daemon |----->| cfg_store | +--------------+ |-+ <==|==> IPC
|
||||
| core | | |---->| backends |-+ |
|
||||
| daemon |----->| backend_- | +--------------+ |-+ <==|==> IPC
|
||||
| core | | manager |---->| backends |-+ |
|
||||
| |----->| | +--------------+ |
|
||||
| | | | |
|
||||
+---------+ +-----------+ |
|
||||
|
||||
@endverbatim
|
||||
* Configuration lookup is done only when acting as responder. For initating
|
||||
* the corresponding controller is responsible to get a config to initiate.
|
||||
*
|
||||
* @b Constructors:
|
||||
* - cfg_store_create()
|
||||
* - backend_manager_create()
|
||||
*
|
||||
* @ingroup config
|
||||
*/
|
||||
struct cfg_store_t {
|
||||
struct backend_manager_t {
|
||||
|
||||
/**
|
||||
* @brief Get an ike_config identified by two hosts.
|
||||
@@ -69,7 +67,7 @@ struct cfg_store_t {
|
||||
* @param other_host address of remote host
|
||||
* @return matching ike_config, or NULL if none found
|
||||
*/
|
||||
ike_cfg_t *(*get_ike_cfg)(cfg_store_t *this,
|
||||
ike_cfg_t *(*get_ike_cfg)(backend_manager_t *this,
|
||||
host_t *my_host, host_t *other_host);
|
||||
|
||||
/**
|
||||
@@ -80,40 +78,41 @@ struct cfg_store_t {
|
||||
* @param other_id peers ID
|
||||
* @return matching peer_config, or NULL if none found
|
||||
*/
|
||||
peer_cfg_t *(*get_peer_cfg)(cfg_store_t *this, identification_t *my_id,
|
||||
peer_cfg_t *(*get_peer_cfg)(backend_manager_t *this, identification_t *my_id,
|
||||
identification_t *other_id);
|
||||
|
||||
/**
|
||||
* @brief Register a backend to be queried by the calls above.
|
||||
* @brief Add a peer_config to the first found writable backend.
|
||||
*
|
||||
* The backend first added is the most preferred.
|
||||
*
|
||||
* @param this calling object
|
||||
* @param this calling object
|
||||
* @param config peer_config to add to the backend
|
||||
*/
|
||||
void (*register_backend) (cfg_store_t *this, backend_t *backend);
|
||||
void (*add_peer_cfg)(backend_manager_t *this, peer_cfg_t *config);
|
||||
|
||||
/**
|
||||
* @brief Unregister a backend.
|
||||
* @brief Create an iterator over all peer configs of the writable backend.
|
||||
*
|
||||
* @param this calling object
|
||||
* @param this calling object
|
||||
* @return iterator over peer configs
|
||||
*/
|
||||
void (*unregister_backend) (cfg_store_t *this, backend_t *backend);
|
||||
iterator_t* (*create_iterator)(backend_manager_t *this);
|
||||
|
||||
/**
|
||||
* @brief Destroys a cfg_store_t object.
|
||||
* @brief Destroys a backend_manager_t object.
|
||||
*
|
||||
* @param this calling object
|
||||
*/
|
||||
void (*destroy) (cfg_store_t *this);
|
||||
void (*destroy) (backend_manager_t *this);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Create a new instance of the store.
|
||||
* @brief Create a new instance of the manager and loads all backends.
|
||||
*
|
||||
* @return cfg_store instance
|
||||
* @return backend_manager instance
|
||||
*
|
||||
* @ingroup config
|
||||
*/
|
||||
cfg_store_t *cfg_store_create(void);
|
||||
backend_manager_t *backend_manager_create(void);
|
||||
|
||||
#endif /*BACKEND_MANAGER_H_*/
|
||||
|
||||
#endif /*CFG_STORE_H_*/
|
||||
@@ -30,7 +30,6 @@ typedef struct backend_t backend_t;
|
||||
#include <config/peer_cfg.h>
|
||||
#include <utils/linked_list.h>
|
||||
|
||||
|
||||
/**
|
||||
* @brief The interface for a configuration backend.
|
||||
*
|
||||
@@ -54,28 +53,48 @@ struct backend_t {
|
||||
* @return matching ike_config, or NULL if none found
|
||||
*/
|
||||
ike_cfg_t *(*get_ike_cfg)(backend_t *this,
|
||||
host_t *my_host, host_t *other_host);
|
||||
host_t *my_host, host_t *other_host);
|
||||
|
||||
/**
|
||||
* @brief Get a peer_cfg identified by two IDs.
|
||||
*
|
||||
* Select a config for two IDs, the others certificate issuer, and
|
||||
* a AC certificate group. The hosts are just a hint to select the
|
||||
* correct config if multiple configs match.
|
||||
*
|
||||
* @param this calling object
|
||||
* @param my_id own ID
|
||||
* @param other_id peers ID
|
||||
* @param my_host address of own host
|
||||
* @param other_host address of remote host
|
||||
* @return matching peer_config, or NULL if none found
|
||||
*/
|
||||
peer_cfg_t *(*get_peer_cfg)(backend_t *this,
|
||||
identification_t *my_id,
|
||||
identification_t *other_id);
|
||||
identification_t *my_id, identification_t *other_id,
|
||||
identification_t *other_ca, char *other_group,
|
||||
host_t *my_host, host_t *other_host);
|
||||
|
||||
/**
|
||||
* @brief Get a peer_cfg identified by its name.
|
||||
* @brief Check if a backend is writable and implements writable_backend_t.
|
||||
*
|
||||
* @param this calling object
|
||||
* @param name configs name
|
||||
* @return matching peer_config, or NULL if none found
|
||||
* @param this calling object
|
||||
* @return TRUE if backend implements writable_backend_t.
|
||||
*/
|
||||
peer_cfg_t *(*get_peer_cfg_by_name)(backend_t *this, char *name);
|
||||
bool (*is_writeable)(backend_t *this);
|
||||
|
||||
/**
|
||||
* @brief Destroy a backend.
|
||||
*
|
||||
* @param this calling object
|
||||
*/
|
||||
void (*destroy)(backend_t *this);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Construction to create a backend.
|
||||
*/
|
||||
typedef backend_t*(*backend_constructor_t)(void);
|
||||
|
||||
#endif /* BACKEND_H_ */
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@ struct private_local_backend_t {
|
||||
};
|
||||
|
||||
/**
|
||||
* implements cfg_store_t.get_ike_cfg.
|
||||
* implements backen_t.get_ike_cfg.
|
||||
*/
|
||||
static ike_cfg_t *get_ike_cfg(private_local_backend_t *this,
|
||||
host_t *my_host, host_t *other_host)
|
||||
@@ -116,11 +116,12 @@ static ike_cfg_t *get_ike_cfg(private_local_backend_t *this,
|
||||
}
|
||||
|
||||
/**
|
||||
* implements cfg_store_t.get_peer.
|
||||
* implements backend_t.get_peer.
|
||||
*/
|
||||
static peer_cfg_t *get_peer_cfg(private_local_backend_t *this,
|
||||
identification_t *my_id,
|
||||
identification_t *other_id)
|
||||
static peer_cfg_t *get_peer_cfg(private_local_backend_t *this,
|
||||
identification_t *my_id, identification_t *other_id,
|
||||
identification_t *other_ca, char *other_group,
|
||||
host_t *my_host, host_t *other_host)
|
||||
{
|
||||
peer_cfg_t *current, *found = NULL;
|
||||
iterator_t *iterator;
|
||||
@@ -166,58 +167,25 @@ static peer_cfg_t *get_peer_cfg(private_local_backend_t *this,
|
||||
}
|
||||
|
||||
/**
|
||||
* implements cfg_store_t.get_peer_by_name.
|
||||
*/
|
||||
static peer_cfg_t *get_peer_cfg_by_name(private_local_backend_t *this,
|
||||
char *name)
|
||||
* Implementation of backend_t.is_writable.
|
||||
*/
|
||||
static bool is_writeable(private_local_backend_t *this)
|
||||
{
|
||||
iterator_t *i1, *i2;
|
||||
peer_cfg_t *current, *found = NULL;
|
||||
child_cfg_t *child;
|
||||
|
||||
i1 = this->cfgs->create_iterator(this->cfgs, TRUE);
|
||||
while (i1->iterate(i1, (void**)¤t))
|
||||
{
|
||||
/* compare peer_cfgs name first */
|
||||
if (streq(current->get_name(current), name))
|
||||
{
|
||||
found = current;
|
||||
found->get_ref(found);
|
||||
break;
|
||||
}
|
||||
/* compare all child_cfg names otherwise */
|
||||
i2 = current->create_child_cfg_iterator(current);
|
||||
while (i2->iterate(i2, (void**)&child))
|
||||
{
|
||||
if (streq(child->get_name(child), name))
|
||||
{
|
||||
found = current;
|
||||
found->get_ref(found);
|
||||
break;
|
||||
}
|
||||
}
|
||||
i2->destroy(i2);
|
||||
if (found)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
i1->destroy(i1);
|
||||
return found;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of local_backend_t.create_peer_cfg_iterator.
|
||||
* Implementation of writable_backend_t.create_iterator.
|
||||
*/
|
||||
static iterator_t* create_peer_cfg_iterator(private_local_backend_t *this)
|
||||
static iterator_t* create_iterator(private_local_backend_t *this)
|
||||
{
|
||||
return this->cfgs->create_iterator_locked(this->cfgs, &this->mutex);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of local_backend_t.add_peer_cfg.
|
||||
* Implementation of writable_backend_t.add_peer_cfg.
|
||||
*/
|
||||
static void add_peer_cfg(private_local_backend_t *this, peer_cfg_t *config)
|
||||
static void add_cfg(private_local_backend_t *this, peer_cfg_t *config)
|
||||
{
|
||||
pthread_mutex_lock(&this->mutex);
|
||||
this->cfgs->insert_last(this->cfgs, config);
|
||||
@@ -225,7 +193,7 @@ static void add_peer_cfg(private_local_backend_t *this, peer_cfg_t *config)
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of local_backend_t.destroy.
|
||||
* Implementation of backend_t.destroy.
|
||||
*/
|
||||
static void destroy(private_local_backend_t *this)
|
||||
{
|
||||
@@ -236,20 +204,20 @@ static void destroy(private_local_backend_t *this)
|
||||
/**
|
||||
* Described in header.
|
||||
*/
|
||||
local_backend_t *local_backend_create(void)
|
||||
backend_t *backend_create(void)
|
||||
{
|
||||
private_local_backend_t *this = malloc_thing(private_local_backend_t);
|
||||
|
||||
this->public.backend.get_ike_cfg = (ike_cfg_t*(*)(backend_t*, host_t *, host_t *))get_ike_cfg;
|
||||
this->public.backend.get_peer_cfg = (peer_cfg_t*(*)(backend_t*, identification_t *, identification_t *))get_peer_cfg;
|
||||
this->public.create_peer_cfg_iterator = (iterator_t*(*)(local_backend_t*))create_peer_cfg_iterator;
|
||||
this->public.get_peer_cfg_by_name = (peer_cfg_t*(*)(local_backend_t*, char *))get_peer_cfg_by_name;
|
||||
this->public.add_peer_cfg = (void(*)(local_backend_t*, peer_cfg_t *))add_peer_cfg;
|
||||
this->public.destroy = (void(*)(local_backend_t*))destroy;
|
||||
this->public.backend.backend.get_ike_cfg = (ike_cfg_t*(*)(backend_t*, host_t *, host_t *))get_ike_cfg;
|
||||
this->public.backend.backend.get_peer_cfg = (peer_cfg_t*(*)(backend_t*,identification_t*,identification_t*,identification_t*,char*,host_t*,host_t*))get_peer_cfg;
|
||||
this->public.backend.backend.is_writeable = (bool(*)(backend_t*))is_writeable;
|
||||
this->public.backend.backend.destroy = (void(*)(backend_t*))destroy;
|
||||
this->public.backend.create_iterator = (iterator_t*(*)(writeable_backend_t*))create_iterator;
|
||||
this->public.backend.add_cfg = (void(*)(writeable_backend_t*, peer_cfg_t *))add_cfg;
|
||||
|
||||
/* private variables */
|
||||
this->cfgs = linked_list_create();
|
||||
pthread_mutex_init(&this->mutex, NULL);
|
||||
|
||||
return (&this->public);
|
||||
return (&this->public.backend.backend);
|
||||
}
|
||||
|
||||
@@ -26,13 +26,13 @@
|
||||
typedef struct local_backend_t local_backend_t;
|
||||
|
||||
#include <library.h>
|
||||
#include <config/backends/backend.h>
|
||||
#include <config/backends/writeable_backend.h>
|
||||
|
||||
/**
|
||||
* @brief An in-memory backend to store configuration information.
|
||||
*
|
||||
* The local_backend_t stores the configuration in a simple list. Additional
|
||||
* to the backend_t functionality, it adds the modification (add/remove).
|
||||
* The local_backend_t stores the configuration in a simple list. It
|
||||
* implements both, backend_t and writeable_backend_t.
|
||||
*
|
||||
* @b Constructors:
|
||||
* - local_backend_create()
|
||||
@@ -42,50 +42,19 @@ typedef struct local_backend_t local_backend_t;
|
||||
struct local_backend_t {
|
||||
|
||||
/**
|
||||
* Implements backend_t interface
|
||||
* Implements writable_backend_t interface
|
||||
*/
|
||||
backend_t backend;
|
||||
|
||||
/**
|
||||
* @brief Add a peer_config to the backend.
|
||||
*
|
||||
* @param this calling object
|
||||
* @param config peer_config to add to the backend
|
||||
*/
|
||||
void (*add_peer_cfg)(local_backend_t *this, peer_cfg_t *config);
|
||||
|
||||
/**
|
||||
* @brief Get a peer_config identified by name, or a name of its child_cfgs.
|
||||
*
|
||||
* @param this calling object
|
||||
* @param name name of the peer config
|
||||
* @return matching peer_config, or NULL if none found
|
||||
*/
|
||||
peer_cfg_t *(*get_peer_cfg_by_name)(local_backend_t *this, char *name);
|
||||
|
||||
/**
|
||||
* @brief Create an iterator over all peer configs.
|
||||
*
|
||||
* @param this calling object
|
||||
* @return iterator over peer configs
|
||||
*/
|
||||
iterator_t* (*create_peer_cfg_iterator)(local_backend_t *this);
|
||||
|
||||
/**
|
||||
* @brief Destroy a local backend.
|
||||
*
|
||||
* @param this calling object
|
||||
*/
|
||||
void (*destroy)(local_backend_t *this);
|
||||
writeable_backend_t backend;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Creates a local_backend_t instance.
|
||||
* @brief Create a backend_t instance implemented as local backend.
|
||||
*
|
||||
* @return local_backend instance.
|
||||
* @return backend instance.
|
||||
*
|
||||
* @ingroup backends
|
||||
*/
|
||||
local_backend_t *local_backend_create(void);
|
||||
backend_t *backend_create(void);
|
||||
|
||||
#endif /* LOCAL_BACKEND_H_ */
|
||||
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
/**
|
||||
* @file writeable_backend.h
|
||||
*
|
||||
* @brief Interface of writeable_backend_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.
|
||||
*/
|
||||
|
||||
#ifndef WRITEABLE_BACKEND_H_
|
||||
#define WRITEABLE_BACKEND_H_
|
||||
|
||||
typedef struct writeable_backend_t writeable_backend_t;
|
||||
|
||||
#include <library.h>
|
||||
#include <config/backends/backend.h>
|
||||
|
||||
/**
|
||||
* @brief A writeable backend extends the backend by modification functions.
|
||||
*
|
||||
* @b Constructors:
|
||||
* - writeable_backend_create()
|
||||
*
|
||||
* @ingroup backends
|
||||
*/
|
||||
struct writeable_backend_t {
|
||||
|
||||
/**
|
||||
* Implements backend_t interface
|
||||
*/
|
||||
backend_t backend;
|
||||
|
||||
/**
|
||||
* @brief Add a peer_config to the backend.
|
||||
*
|
||||
* @param this calling object
|
||||
* @param config peer_config to add to the backend
|
||||
*/
|
||||
void (*add_cfg)(writeable_backend_t *this, peer_cfg_t *config);
|
||||
|
||||
/**
|
||||
* @brief Create an iterator over all peer configs.
|
||||
*
|
||||
* @param this calling object
|
||||
* @return iterator over peer configs
|
||||
*/
|
||||
iterator_t* (*create_iterator)(writeable_backend_t *this);
|
||||
};
|
||||
|
||||
#endif /* WRITEABLE_BACKEND_H_ */
|
||||
|
||||
@@ -1,146 +0,0 @@
|
||||
/**
|
||||
* @file cfg_store.c
|
||||
*
|
||||
* @brief Implementation of cfg_store_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 <pthread.h>
|
||||
|
||||
#include "cfg_store.h"
|
||||
|
||||
#include <library.h>
|
||||
#include <utils/linked_list.h>
|
||||
|
||||
|
||||
typedef struct private_cfg_store_t private_cfg_store_t;
|
||||
|
||||
/**
|
||||
* Private data of an cfg_store_t object.
|
||||
*/
|
||||
struct private_cfg_store_t {
|
||||
|
||||
/**
|
||||
* Public part of cfg_store_t object.
|
||||
*/
|
||||
cfg_store_t public;
|
||||
|
||||
/**
|
||||
* list of registered backends
|
||||
*/
|
||||
linked_list_t *backends;
|
||||
|
||||
/**
|
||||
* mutex to lock backend list
|
||||
*/
|
||||
pthread_mutex_t mutex;
|
||||
};
|
||||
|
||||
/**
|
||||
* implements cfg_store_t.get_ike.
|
||||
*/
|
||||
static ike_cfg_t *get_ike_cfg(private_cfg_store_t *this,
|
||||
host_t *my_host, host_t *other_host)
|
||||
{
|
||||
backend_t *backend;
|
||||
ike_cfg_t *config = NULL;
|
||||
iterator_t *iterator = this->backends->create_iterator_locked(
|
||||
this->backends, &this->mutex);
|
||||
while (config == NULL && iterator->iterate(iterator, (void**)&backend))
|
||||
{
|
||||
config = backend->get_ike_cfg(backend, my_host, other_host);
|
||||
}
|
||||
iterator->destroy(iterator);
|
||||
return config;
|
||||
}
|
||||
|
||||
/**
|
||||
* implements cfg_store_t.get_peer.
|
||||
*/
|
||||
static peer_cfg_t *get_peer_cfg(private_cfg_store_t *this,
|
||||
identification_t *my_id,
|
||||
identification_t *other_id)
|
||||
{
|
||||
backend_t *backend;
|
||||
peer_cfg_t *config = NULL;
|
||||
iterator_t *iterator = this->backends->create_iterator_locked(
|
||||
this->backends, &this->mutex);
|
||||
while (config == NULL && iterator->iterate(iterator, (void**)&backend))
|
||||
{
|
||||
config = backend->get_peer_cfg(backend, my_id, other_id);
|
||||
}
|
||||
iterator->destroy(iterator);
|
||||
return config;
|
||||
}
|
||||
|
||||
/**
|
||||
* implements cfg_store_t.register_backend.
|
||||
*/
|
||||
static void register_backend(private_cfg_store_t *this, backend_t *backend)
|
||||
{
|
||||
pthread_mutex_lock(&this->mutex);
|
||||
this->backends->insert_last(this->backends, backend);
|
||||
pthread_mutex_unlock(&this->mutex);
|
||||
}
|
||||
|
||||
/**
|
||||
* implements cfg_store_t.unregister_backend.
|
||||
*/
|
||||
static void unregister_backend(private_cfg_store_t *this, backend_t *backend)
|
||||
{
|
||||
backend_t *current;
|
||||
iterator_t *iterator = this->backends->create_iterator_locked(
|
||||
this->backends, &this->mutex);
|
||||
while (iterator->iterate(iterator, (void**)¤t))
|
||||
{
|
||||
if (backend == current)
|
||||
{
|
||||
iterator->remove(iterator);
|
||||
break;
|
||||
}
|
||||
}
|
||||
iterator->destroy(iterator);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of cfg_store_t.destroy.
|
||||
*/
|
||||
static void destroy(private_cfg_store_t *this)
|
||||
{
|
||||
this->backends->destroy(this->backends);
|
||||
free(this);
|
||||
}
|
||||
|
||||
/*
|
||||
* Described in header-file
|
||||
*/
|
||||
cfg_store_t *cfg_store_create()
|
||||
{
|
||||
private_cfg_store_t *this = malloc_thing(private_cfg_store_t);
|
||||
|
||||
this->public.get_ike_cfg = (ike_cfg_t*(*)(cfg_store_t*, host_t *, host_t *))get_ike_cfg;
|
||||
this->public.get_peer_cfg = (peer_cfg_t*(*)(cfg_store_t*, identification_t *, identification_t *))get_peer_cfg;
|
||||
this->public.register_backend = (void(*)(cfg_store_t*, backend_t *))register_backend;
|
||||
this->public.unregister_backend = (void(*)(cfg_store_t*, backend_t *))unregister_backend;
|
||||
this->public.destroy = (void(*)(cfg_store_t*))destroy;
|
||||
|
||||
this->backends = linked_list_create();
|
||||
pthread_mutex_init(&this->mutex, NULL);
|
||||
|
||||
return &this->public;
|
||||
}
|
||||
Reference in New Issue
Block a user