]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
hostapd: Force RADIUS socket renewal on RADIUS auth failures
authorHelmut Schaa <helmut.schaa@googlemail.com>
Wed, 16 Sep 2015 12:04:56 +0000 (14:04 +0200)
committerJouni Malinen <j@w1.fi>
Mon, 5 Oct 2015 22:27:29 +0000 (01:27 +0300)
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>
src/radius/radius_client.c

index 693f61ea04552fc479b3ccccf0d27aa87c0dc82c..0bcdb45339140396758138689e44968606c8cc4e 100644 (file)
@@ -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;