aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMartin Willi <martin@revosec.ch>2011-04-12 11:36:03 +0200
committerMartin Willi <martin@revosec.ch>2011-04-15 10:07:13 +0200
commitf0331baf1a7f28846bb34011c528e7907972004d (patch)
treec7e8944db9035d2fdb984de5e6e0f74f4dc80cc9 /src
parent3b71d3d033e70591d6857b4504d7577eaa630a12 (diff)
downloadstrongswan-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.c81
-rw-r--r--src/libcharon/plugins/eap_radius/radius_client.c4
-rw-r--r--src/libcharon/plugins/eap_radius/radius_server.c30
-rw-r--r--src/libcharon/plugins/eap_radius/radius_server.h7
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);