aboutsummaryrefslogtreecommitdiffstats
path: root/src/radius
diff options
context:
space:
mode:
authorHelmut Schaa <helmut.schaa@googlemail.com>2015-09-16 12:04:56 (GMT)
committerJouni Malinen <j@w1.fi>2015-10-05 22:27:29 (GMT)
commite5d34da25acb59daee215ea1fb4a49338430b341 (patch)
treeacb53628a428d8dff1c8cca699a3d64a0459bd3c /src/radius
parent681753f23cdcf636a6bfcde275e79c716a849c62 (diff)
downloadhostap-e5d34da25acb59daee215ea1fb4a49338430b341.zip
hostap-e5d34da25acb59daee215ea1fb4a49338430b341.tar.gz
hostap-e5d34da25acb59daee215ea1fb4a49338430b341.tar.bz2
hostapd: Force RADIUS socket renewal on RADIUS auth failures
On RADIUS auth/acct failures hostapd will try a new server if one is available. Reuse the failover logic to force a socket renewal if only one RADIUS server is configured. This fixes problems when a route for the RADIUS server gets added after the socket was "connected". The RADIUS socket is still sending the RADIUS requests out using the previous route. Signed-off-by: Helmut Schaa <helmut.schaa@googlemail.com>
Diffstat (limited to 'src/radius')
-rw-r--r--src/radius/radius_client.c19
1 files changed, 16 insertions, 3 deletions
diff --git a/src/radius/radius_client.c b/src/radius/radius_client.c
index 693f61e..0bcdb45 100644
--- a/src/radius/radius_client.c
+++ b/src/radius/radius_client.c
@@ -407,7 +407,6 @@ static int radius_client_retransmit(struct radius_client_data *radius,
static void radius_client_timer(void *eloop_ctx, void *timeout_ctx)
{
struct radius_client_data *radius = eloop_ctx;
- struct hostapd_radius_servers *conf = radius->conf;
struct os_reltime now;
os_time_t first;
struct radius_msg_list *entry, *prev, *tmp;
@@ -476,10 +475,10 @@ static void radius_client_timer(void *eloop_ctx, void *timeout_ctx)
(long int) (first - now.sec));
}
- if (auth_failover && conf->num_auth_servers > 1)
+ if (auth_failover)
radius_client_auth_failover(radius);
- if (acct_failover && conf->num_acct_servers > 1)
+ if (acct_failover)
radius_client_acct_failover(radius);
}
@@ -1015,6 +1014,9 @@ radius_change_server(struct radius_client_data *radius,
int sel_sock;
struct radius_msg_list *entry;
struct hostapd_radius_servers *conf = radius->conf;
+ struct sockaddr_in disconnect_addr = {
+ .sin_family = AF_UNSPEC,
+ };
hostapd_logger(radius->ctx, NULL, HOSTAPD_MODULE_RADIUS,
HOSTAPD_LEVEL_INFO,
@@ -1023,6 +1025,12 @@ radius_change_server(struct radius_client_data *radius,
hostapd_ip_txt(&nserv->addr, abuf, sizeof(abuf)),
nserv->port);
+ if (oserv && oserv == nserv) {
+ /* Reconnect to same server, flush */
+ if (auth)
+ radius_client_flush(radius, 1);
+ }
+
if (oserv && oserv != nserv &&
(nserv->shared_secret_len != oserv->shared_secret_len ||
os_memcmp(nserv->shared_secret, oserv->shared_secret,
@@ -1125,6 +1133,11 @@ radius_change_server(struct radius_client_data *radius,
}
}
+ /* Force a reconnect by disconnecting the socket first */
+ if (connect(sel_sock, (struct sockaddr *) &disconnect_addr,
+ sizeof(disconnect_addr)) < 0)
+ wpa_printf(MSG_INFO, "disconnect[radius]: %s", strerror(errno));
+
if (connect(sel_sock, addr, addrlen) < 0) {
wpa_printf(MSG_INFO, "connect[radius]: %s", strerror(errno));
return -1;