eap-radius: Add ability to configure RADIUS retransmission behavior
Closes strongswan/strongswan#19.
This commit is contained in:
parent
8e9adf3d09
commit
ac36ede93c
|
@ -80,6 +80,15 @@ charon.plugins.eap-radius.secret =
|
|||
charon.plugins.eap-radius.server =
|
||||
IP/Hostname of RADIUS server.
|
||||
|
||||
charon.plugins.eap-radius.retransmit_base = 1.4
|
||||
Base to use for calculating exponential back off.
|
||||
|
||||
charon.plugins.eap-radius.retransmit_timeout = 2.0
|
||||
Timeout in seconds before sending first retransmit.
|
||||
|
||||
charon.plugins.eap-radius.retransmit_tries = 4
|
||||
Number of times to retransmit a packet before giving up.
|
||||
|
||||
charon.plugins.eap-radius.servers {}
|
||||
Section to specify multiple RADIUS servers.
|
||||
|
||||
|
@ -88,7 +97,9 @@ charon.plugins.eap-radius.servers {}
|
|||
specified for each server. A server's IP/Hostname can be configured using
|
||||
the **address** option. The **acct_port** [1813] option can be used to
|
||||
specify the port used for RADIUS accounting. For each RADIUS server a
|
||||
priority can be specified using the **preference** [0] option.
|
||||
priority can be specified using the **preference** [0] option. The
|
||||
retransmission time for each server can set set using **retransmit_base**,
|
||||
**retransmit_timeout** and **retransmit_tries**.
|
||||
|
||||
charon.plugins.eap-radius.sockets = 1
|
||||
Number of sockets (ports) to use, increase for high load.
|
||||
|
|
|
@ -14,6 +14,28 @@
|
|||
* for more details.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2015 Thom Troy
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "eap_radius_plugin.h"
|
||||
|
||||
#include "eap_radius.h"
|
||||
|
@ -98,6 +120,8 @@ static void load_configs(private_eap_radius_plugin_t *this)
|
|||
radius_config_t *config;
|
||||
char *nas_identifier, *secret, *address, *section;
|
||||
int auth_port, acct_port, sockets, preference;
|
||||
u_int retransmit_tries;
|
||||
double retransmit_timeout, retransmit_base;
|
||||
|
||||
address = lib->settings->get_str(lib->settings,
|
||||
"%s.plugins.eap-radius.server", NULL, lib->ns);
|
||||
|
@ -117,8 +141,18 @@ static void load_configs(private_eap_radius_plugin_t *this)
|
|||
"%s.plugins.eap-radius.port", AUTH_PORT, lib->ns);
|
||||
sockets = lib->settings->get_int(lib->settings,
|
||||
"%s.plugins.eap-radius.sockets", 1, lib->ns);
|
||||
|
||||
retransmit_tries = lib->settings->get_int(lib->settings,
|
||||
"%s.plugins.eap-radius.retransmit_tries", 4, lib->ns);
|
||||
retransmit_timeout = lib->settings->get_double(lib->settings,
|
||||
"%s.plugins.eap-radius.retransmit_timeout", 2, lib->ns);
|
||||
retransmit_base = lib->settings->get_double(lib->settings,
|
||||
"%s.plugins.eap-radius.retransmit_base", 1.4, lib->ns);
|
||||
|
||||
config = radius_config_create(address, address, auth_port, ACCT_PORT,
|
||||
nas_identifier, secret, sockets, 0);
|
||||
nas_identifier, secret, sockets, 0,
|
||||
retransmit_tries, retransmit_timeout,
|
||||
retransmit_base);
|
||||
if (!config)
|
||||
{
|
||||
DBG1(DBG_CFG, "no RADUIS server defined");
|
||||
|
@ -170,11 +204,33 @@ static void load_configs(private_eap_radius_plugin_t *this)
|
|||
lib->settings->get_int(lib->settings,
|
||||
"%s.plugins.eap-radius.sockets", 1, lib->ns),
|
||||
lib->ns, section);
|
||||
|
||||
retransmit_tries = lib->settings->get_int(lib->settings,
|
||||
"%s.plugins.eap-radius.servers.%s.retransmit_tries",
|
||||
lib->settings->get_int(lib->settings,
|
||||
"%s.plugins.eap-radius.retransmit_tries", 4, lib->ns),
|
||||
lib->ns, section);
|
||||
|
||||
retransmit_timeout = lib->settings->get_double(lib->settings,
|
||||
"%s.plugins.eap-radius.servers.%s.retransmit_timeout",
|
||||
lib->settings->get_double(lib->settings,
|
||||
"%s.plugins.eap-radius.retransmit_timeout", 2, lib->ns),
|
||||
lib->ns, section);
|
||||
|
||||
retransmit_base = lib->settings->get_double(lib->settings,
|
||||
"%s.plugins.eap-radius.servers.%s.retransmit_base",
|
||||
lib->settings->get_double(lib->settings,
|
||||
"%s.plugins.eap-radius.retransmit_base", 1.4, lib->ns),
|
||||
lib->ns, section);
|
||||
|
||||
preference = lib->settings->get_int(lib->settings,
|
||||
"%s.plugins.eap-radius.servers.%s.preference", 0,
|
||||
lib->ns, section);
|
||||
|
||||
config = radius_config_create(section, address, auth_port, acct_port,
|
||||
nas_identifier, secret, sockets, preference);
|
||||
nas_identifier, secret, sockets, preference,
|
||||
retransmit_tries, retransmit_timeout,
|
||||
retransmit_base);
|
||||
if (!config)
|
||||
{
|
||||
DBG1(DBG_CFG, "loading RADIUS server '%s' failed, skipped", section);
|
||||
|
|
|
@ -7,7 +7,7 @@ AM_LDFLAGS = \
|
|||
ipseclib_LTLIBRARIES = libradius.la
|
||||
|
||||
libradius_la_LIBADD = \
|
||||
$(top_builddir)/src/libstrongswan/libstrongswan.la
|
||||
$(top_builddir)/src/libstrongswan/libstrongswan.la -lm
|
||||
|
||||
libradius_la_SOURCES = \
|
||||
radius_message.h radius_message.c \
|
||||
|
|
|
@ -13,6 +13,28 @@
|
|||
* for more details.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2015 Thom Troy
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "radius_config.h"
|
||||
|
||||
#include <threading/mutex.h>
|
||||
|
@ -180,7 +202,8 @@ METHOD(radius_config_t, destroy, void,
|
|||
radius_config_t *radius_config_create(char *name, char *address,
|
||||
u_int16_t auth_port, u_int16_t acct_port,
|
||||
char *nas_identifier, char *secret,
|
||||
int sockets, int preference)
|
||||
int sockets, int preference,
|
||||
u_int tries, double timeout, double base)
|
||||
{
|
||||
private_radius_config_t *this;
|
||||
radius_socket_t *socket;
|
||||
|
@ -209,7 +232,8 @@ radius_config_t *radius_config_create(char *name, char *address,
|
|||
while (sockets--)
|
||||
{
|
||||
socket = radius_socket_create(address, auth_port, acct_port,
|
||||
chunk_create(secret, strlen(secret)));
|
||||
chunk_create(secret, strlen(secret)),
|
||||
tries, timeout, base);
|
||||
if (!socket)
|
||||
{
|
||||
destroy(this);
|
||||
|
|
|
@ -13,6 +13,28 @@
|
|||
* for more details.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2015 Thom Troy
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup radius_config radius_config
|
||||
* @{ @ingroup libradius
|
||||
|
@ -91,10 +113,14 @@ struct radius_config_t {
|
|||
* @param secret secret to use with this server
|
||||
* @param sockets number of sockets to create in pool
|
||||
* @param preference preference boost for this server
|
||||
* @param tries number of times we retransmit messages
|
||||
* @param timeout retransmission timeout
|
||||
* @param base base to calculate retransmission timeout
|
||||
*/
|
||||
radius_config_t *radius_config_create(char *name, char *address,
|
||||
u_int16_t auth_port, u_int16_t acct_port,
|
||||
char *nas_identifier, char *secret,
|
||||
int sockets, int preference);
|
||||
int sockets, int preference,
|
||||
u_int tries, double timeout, double base);
|
||||
|
||||
#endif /** RADIUS_CONFIG_H_ @}*/
|
||||
|
|
|
@ -13,11 +13,34 @@
|
|||
* for more details.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2015 Thom Troy
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "radius_socket.h"
|
||||
#include "radius_mppe.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <math.h>
|
||||
|
||||
#include <pen/pen.h>
|
||||
#include <utils/debug.h>
|
||||
|
@ -83,6 +106,21 @@ struct private_radius_socket_t {
|
|||
* RADIUS secret
|
||||
*/
|
||||
chunk_t secret;
|
||||
|
||||
/**
|
||||
* Number of times we retransmit messages before giving up
|
||||
*/
|
||||
u_int retransmit_tries;
|
||||
|
||||
/**
|
||||
* Retransmission timeout
|
||||
*/
|
||||
double retransmit_timeout;
|
||||
|
||||
/**
|
||||
* Base to calculate retransmission timeout
|
||||
*/
|
||||
double retransmit_base;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -185,7 +223,7 @@ METHOD(radius_socket_t, request, radius_message_t*,
|
|||
{
|
||||
radius_message_t *response;
|
||||
chunk_t data;
|
||||
int i, *fd, retransmit = 0;
|
||||
int *fd, retransmit = 0, timeout;
|
||||
u_int16_t port;
|
||||
rng_t *rng = NULL;
|
||||
|
||||
|
@ -218,21 +256,22 @@ METHOD(radius_socket_t, request, radius_message_t*,
|
|||
data = request->get_encoding(request);
|
||||
DBG3(DBG_CFG, "%B", &data);
|
||||
|
||||
/* timeout after 2, 3, 4, 5 seconds */
|
||||
for (i = 2; i <= 5; i++)
|
||||
while (retransmit < this->retransmit_tries)
|
||||
{
|
||||
timeout = (int)(this->retransmit_timeout * 1000.0 *
|
||||
pow(this->retransmit_base, retransmit));
|
||||
if (retransmit)
|
||||
{
|
||||
DBG1(DBG_CFG, "retransmitting RADIUS %N (attempt %d)",
|
||||
radius_message_code_names, request->get_code(request),
|
||||
retransmit);
|
||||
DBG1(DBG_CFG, "retransmit %d of RADIUS %N (timeout: %.1fs)",
|
||||
retransmit, radius_message_code_names,
|
||||
request->get_code(request), timeout/1000.0);
|
||||
}
|
||||
if (send(*fd, data.ptr, data.len, 0) != data.len)
|
||||
{
|
||||
DBG1(DBG_CFG, "sending RADIUS message failed: %s", strerror(errno));
|
||||
return NULL;
|
||||
}
|
||||
switch (receive_response(*fd, i*1000, request->get_identifier(request),
|
||||
switch (receive_response(*fd, timeout, request->get_identifier(request),
|
||||
&response))
|
||||
{
|
||||
case SUCCESS:
|
||||
|
@ -251,8 +290,9 @@ METHOD(radius_socket_t, request, radius_message_t*,
|
|||
response->destroy(response);
|
||||
return NULL;
|
||||
}
|
||||
DBG1(DBG_CFG, "RADIUS %N timed out after %d retransmits",
|
||||
radius_message_code_names, request->get_code(request), retransmit - 1);
|
||||
|
||||
DBG1(DBG_CFG, "RADIUS %N timed out after %d attempts",
|
||||
radius_message_code_names, request->get_code(request), retransmit);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -336,7 +376,8 @@ METHOD(radius_socket_t, destroy, void,
|
|||
* See header
|
||||
*/
|
||||
radius_socket_t *radius_socket_create(char *address, u_int16_t auth_port,
|
||||
u_int16_t acct_port, chunk_t secret)
|
||||
u_int16_t acct_port, chunk_t secret,
|
||||
u_int tries, double timeout, double base)
|
||||
{
|
||||
private_radius_socket_t *this;
|
||||
|
||||
|
@ -354,6 +395,9 @@ radius_socket_t *radius_socket_create(char *address, u_int16_t auth_port,
|
|||
.hasher = lib->crypto->create_hasher(lib->crypto, HASH_MD5),
|
||||
.signer = lib->crypto->create_signer(lib->crypto, AUTH_HMAC_MD5_128),
|
||||
.rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK),
|
||||
.retransmit_tries = tries,
|
||||
.retransmit_timeout = timeout,
|
||||
.retransmit_base = base,
|
||||
);
|
||||
|
||||
if (!this->hasher || !this->signer || !this->rng ||
|
||||
|
|
|
@ -13,6 +13,28 @@
|
|||
* for more details.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2015 Thom Troy
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup radius_socket radius_socket
|
||||
* @{ @ingroup libradius
|
||||
|
@ -70,8 +92,12 @@ struct radius_socket_t {
|
|||
* @param auth_port server port for authentication
|
||||
* @param acct_port server port for accounting
|
||||
* @param secret RADIUS secret
|
||||
* @param tries number of times we retransmit messages
|
||||
* @param timeout retransmission timeout
|
||||
* @param base base to calculate retransmission timeout
|
||||
*/
|
||||
radius_socket_t *radius_socket_create(char *address, u_int16_t auth_port,
|
||||
u_int16_t acct_port, chunk_t secret);
|
||||
u_int16_t acct_port, chunk_t secret,
|
||||
u_int tries, double timeout, double base);
|
||||
|
||||
#endif /** RADIUS_SOCKET_H_ @}*/
|
||||
|
|
Loading…
Reference in New Issue