diff options
author | Helmut Schaa <helmut.schaa@googlemail.com> | 2015-09-16 12:04:56 (GMT) |
---|---|---|
committer | Jouni Malinen <j@w1.fi> | 2015-10-05 22:27:29 (GMT) |
commit | e5d34da25acb59daee215ea1fb4a49338430b341 (patch) | |
tree | acb53628a428d8dff1c8cca699a3d64a0459bd3c /src/radius | |
parent | 681753f23cdcf636a6bfcde275e79c716a849c62 (diff) | |
download | hostap-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.c | 19 |
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; |