diff options
author | Martin Willi <martin@revosec.ch> | 2011-04-12 11:36:03 +0200 |
---|---|---|
committer | Martin Willi <martin@revosec.ch> | 2011-04-15 10:07:13 +0200 |
commit | f0331baf1a7f28846bb34011c528e7907972004d (patch) | |
tree | c7e8944db9035d2fdb984de5e6e0f74f4dc80cc9 /src | |
parent | 3b71d3d033e70591d6857b4504d7577eaa630a12 (diff) | |
download | strongswan-f0331baf1a7f28846bb34011c528e7907972004d.tar.bz2 strongswan-f0331baf1a7f28846bb34011c528e7907972004d.tar.xz |
Added reload support to eap-radius plugin
Diffstat (limited to 'src')
-rw-r--r-- | src/libcharon/plugins/eap_radius/eap_radius_plugin.c | 81 | ||||
-rw-r--r-- | src/libcharon/plugins/eap_radius/radius_client.c | 4 | ||||
-rw-r--r-- | src/libcharon/plugins/eap_radius/radius_server.c | 30 | ||||
-rw-r--r-- | src/libcharon/plugins/eap_radius/radius_server.h | 7 |
4 files changed, 83 insertions, 39 deletions
diff --git a/src/libcharon/plugins/eap_radius/eap_radius_plugin.c b/src/libcharon/plugins/eap_radius/eap_radius_plugin.c index 7ae3da017..9b1525662 100644 --- a/src/libcharon/plugins/eap_radius/eap_radius_plugin.c +++ b/src/libcharon/plugins/eap_radius/eap_radius_plugin.c @@ -20,6 +20,7 @@ #include "radius_server.h" #include <daemon.h> +#include <threading/rwlock.h> /** * Default RADIUS server port, when not configured @@ -42,6 +43,11 @@ struct private_eap_radius_plugin_t { * List of RADIUS servers */ linked_list_t *servers; + + /** + * Lock for server list + */ + rwlock_t *lock; }; /** @@ -49,26 +55,10 @@ struct private_eap_radius_plugin_t { */ static private_eap_radius_plugin_t *instance = NULL; -METHOD(plugin_t, get_name, char*, - private_eap_radius_plugin_t *this) -{ - return "eap-radius"; -} - -METHOD(plugin_t, destroy, void, - private_eap_radius_plugin_t *this) -{ - charon->eap->remove_method(charon->eap, (eap_constructor_t)eap_radius_create); - this->servers->destroy_offset(this->servers, - offsetof(radius_server_t, destroy)); - free(this); - instance = NULL; -} - /** * Load RADIUS servers from configuration */ -static bool load_servers(private_eap_radius_plugin_t *this) +static void load_servers(private_eap_radius_plugin_t *this) { enumerator_t *enumerator; radius_server_t *server; @@ -84,7 +74,7 @@ static bool load_servers(private_eap_radius_plugin_t *this) if (!secret) { DBG1(DBG_CFG, "no RADUIS secret defined"); - return FALSE; + return; } nas_identifier = lib->settings->get_str(lib->settings, "charon.plugins.eap-radius.nas_identifier", "strongSwan"); @@ -97,10 +87,10 @@ static bool load_servers(private_eap_radius_plugin_t *this) if (!server) { DBG1(DBG_CFG, "no RADUIS server defined"); - return FALSE; + return; } this->servers->insert_last(this->servers, server); - return TRUE; + return; } enumerator = lib->settings->create_section_enumerator(lib->settings, @@ -141,14 +131,40 @@ static bool load_servers(private_eap_radius_plugin_t *this) } enumerator->destroy(enumerator); - if (this->servers->get_count(this->servers) == 0) - { - DBG1(DBG_CFG, "no valid RADIUS server configuration found"); - return FALSE; - } + DBG1(DBG_CFG, "loaded %d RADIUS server configuration%s", + this->servers->get_count(this->servers), + this->servers->get_count(this->servers) == 1 ? "" : "s"); +} + +METHOD(plugin_t, get_name, char*, + private_eap_radius_plugin_t *this) +{ + return "eap-radius"; +} + +METHOD(plugin_t, reload, bool, + private_eap_radius_plugin_t *this) +{ + this->lock->write_lock(this->lock); + this->servers->destroy_offset(this->servers, + offsetof(radius_server_t, destroy)); + this->servers = linked_list_create(); + load_servers(this); + this->lock->unlock(this->lock); return TRUE; } +METHOD(plugin_t, destroy, void, + private_eap_radius_plugin_t *this) +{ + charon->eap->remove_method(charon->eap, (eap_constructor_t)eap_radius_create); + this->servers->destroy_offset(this->servers, + offsetof(radius_server_t, destroy)); + this->lock->destroy(this->lock); + free(this); + instance = NULL; +} + /* * see header file */ @@ -160,18 +176,16 @@ plugin_t *eap_radius_plugin_create() .public = { .plugin = { .get_name = _get_name, - .reload = (void*)return_false, + .reload = _reload, .destroy = _destroy, }, }, .servers = linked_list_create(), + .lock = rwlock_create(RWLOCK_TYPE_DEFAULT), ); - if (!load_servers(this)) - { - destroy(this); - return NULL; - } + load_servers(this); + charon->eap->add_method(charon->eap, EAP_RADIUS, 0, EAP_SERVER, (eap_constructor_t)eap_radius_create); @@ -187,7 +201,10 @@ enumerator_t *eap_radius_create_server_enumerator() { if (instance) { - return instance->servers->create_enumerator(instance->servers); + instance->lock->read_lock(instance->lock); + return enumerator_create_cleaner( + instance->servers->create_enumerator(instance->servers), + (void*)instance->lock->unlock, instance->lock); } return enumerator_create_empty(); } diff --git a/src/libcharon/plugins/eap_radius/radius_client.c b/src/libcharon/plugins/eap_radius/radius_client.c index 232b9135e..0d7276af4 100644 --- a/src/libcharon/plugins/eap_radius/radius_client.c +++ b/src/libcharon/plugins/eap_radius/radius_client.c @@ -128,6 +128,7 @@ METHOD(radius_client_t, get_msk, chunk_t, METHOD(radius_client_t, destroy, void, private_radius_client_t *this) { + this->server->destroy(this->server); chunk_clear(&this->msk); free(this->state.ptr); free(this); @@ -162,7 +163,8 @@ radius_client_t *radius_client_create() DBG2(DBG_CFG, "RADIUS server %H is candidate: %d", server->get_address(server), current); best = current; - this->server = server; + DESTROY_IF(this->server); + this->server = server->get_ref(server); } else { diff --git a/src/libcharon/plugins/eap_radius/radius_server.c b/src/libcharon/plugins/eap_radius/radius_server.c index f54b8b2cd..d16628091 100644 --- a/src/libcharon/plugins/eap_radius/radius_server.c +++ b/src/libcharon/plugins/eap_radius/radius_server.c @@ -80,6 +80,11 @@ struct private_radius_server_t { * Retry counter for unreachable servers */ int retry; + + /** + * reference count + */ + refcount_t ref; }; METHOD(radius_server_t, get_socket, radius_socket_t*, @@ -153,15 +158,26 @@ METHOD(radius_server_t, get_address, host_t*, return this->host; } +METHOD(radius_server_t, get_ref, radius_server_t*, + private_radius_server_t *this) +{ + ref_get(&this->ref); + return &this->public; +} + + METHOD(radius_server_t, destroy, void, private_radius_server_t *this) { - DESTROY_IF(this->host); - this->mutex->destroy(this->mutex); - this->condvar->destroy(this->condvar); - this->sockets->destroy_offset(this->sockets, - offsetof(radius_socket_t, destroy)); - free(this); + if (ref_put(&this->ref)) + { + DESTROY_IF(this->host); + this->mutex->destroy(this->mutex); + this->condvar->destroy(this->condvar); + this->sockets->destroy_offset(this->sockets, + offsetof(radius_socket_t, destroy)); + free(this); + } } /** @@ -180,6 +196,7 @@ radius_server_t *radius_server_create(char *server, u_int16_t port, .get_nas_identifier = _get_nas_identifier, .get_preference = _get_preference, .get_address = _get_address, + .get_ref = _get_ref, .destroy = _destroy, }, .reachable = TRUE, @@ -190,6 +207,7 @@ radius_server_t *radius_server_create(char *server, u_int16_t port, .condvar = condvar_create(CONDVAR_TYPE_DEFAULT), .host = host_create_from_dns(server, 0, port), .preference = preference, + .ref = 1, ); if (!this->host) diff --git a/src/libcharon/plugins/eap_radius/radius_server.h b/src/libcharon/plugins/eap_radius/radius_server.h index ba4c94619..a9bc72180 100644 --- a/src/libcharon/plugins/eap_radius/radius_server.h +++ b/src/libcharon/plugins/eap_radius/radius_server.h @@ -68,6 +68,13 @@ struct radius_server_t { host_t* (*get_address)(radius_server_t *this); /** + * Increase reference count of this server. + * + * @return this + */ + radius_server_t* (*get_ref)(radius_server_t *this); + + /** * Destroy a radius_server_t. */ void (*destroy)(radius_server_t *this); |