X-Git-Url: http://www.project-moonshot.org/gitweb/?p=mech_eap.git;a=blobdiff_plain;f=libeap%2Fsrc%2Fradius%2Fradius_client.c;h=693f61ea04552fc479b3ccccf0d27aa87c0dc82c;hp=171af2927b0fb903ecf0156784ab2f5b58ad66ed;hb=4f319dde67a76fe0aaf33f6d2788968012584ada;hpb=ed09b5e64dd485851310307979d5eed14678087b diff --git a/libeap/src/radius/radius_client.c b/libeap/src/radius/radius_client.c index 171af29..693f61e 100644 --- a/libeap/src/radius/radius_client.c +++ b/libeap/src/radius/radius_client.c @@ -1,15 +1,9 @@ /* * RADIUS client - * Copyright (c) 2002-2009, Jouni Malinen + * Copyright (c) 2002-2015, Jouni Malinen * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Alternatively, this software may be distributed under the terms of BSD - * license. - * - * See README and COPYING for more details. + * This software may be distributed under the terms of the BSD license. + * See README for more details. */ #include "includes.h" @@ -128,7 +122,7 @@ struct radius_msg_list { /** * last_attempt - Time of the last transmission attempt */ - struct os_time last_attempt; + struct os_reltime last_attempt; /** * shared_secret - Shared secret with the target RADIUS server @@ -242,6 +236,8 @@ radius_change_server(struct radius_client_data *radius, int sock, int sock6, int auth); static int radius_client_init_acct(struct radius_client_data *radius); static int radius_client_init_auth(struct radius_client_data *radius); +static void radius_client_auth_failover(struct radius_client_data *radius); +static void radius_client_acct_failover(struct radius_client_data *radius); static void radius_client_msg_free(struct radius_msg_list *req) @@ -287,8 +283,8 @@ int radius_client_register(struct radius_client_data *radius, num = &radius->num_auth_handlers; } - newh = os_realloc(*handlers, - (*num + 1) * sizeof(struct radius_rx_handler)); + newh = os_realloc_array(*handlers, *num + 1, + sizeof(struct radius_rx_handler)); if (newh == NULL) return -1; @@ -301,26 +297,34 @@ int radius_client_register(struct radius_client_data *radius, } -static void radius_client_handle_send_error(struct radius_client_data *radius, - int s, RadiusType msg_type) +/* + * Returns >0 if message queue was flushed (i.e., the message that triggered + * the error is not available anymore) + */ +static int radius_client_handle_send_error(struct radius_client_data *radius, + int s, RadiusType msg_type) { #ifndef CONFIG_NATIVE_WINDOWS int _errno = errno; - perror("send[RADIUS]"); + wpa_printf(MSG_INFO, "send[RADIUS,s=%d]: %s", s, strerror(errno)); if (_errno == ENOTCONN || _errno == EDESTADDRREQ || _errno == EINVAL || - _errno == EBADF) { + _errno == EBADF || _errno == ENETUNREACH) { hostapd_logger(radius->ctx, NULL, HOSTAPD_MODULE_RADIUS, HOSTAPD_LEVEL_INFO, "Send failed - maybe interface status changed -" " try to connect again"); - eloop_unregister_read_sock(s); - close(s); - if (msg_type == RADIUS_ACCT || msg_type == RADIUS_ACCT_INTERIM) + if (msg_type == RADIUS_ACCT || + msg_type == RADIUS_ACCT_INTERIM) { radius_client_init_acct(radius); - else + return 0; + } else { radius_client_init_auth(radius); + return 1; + } } #endif /* CONFIG_NATIVE_WINDOWS */ + + return 0; } @@ -331,9 +335,18 @@ static int radius_client_retransmit(struct radius_client_data *radius, struct hostapd_radius_servers *conf = radius->conf; int s; struct wpabuf *buf; + size_t prev_num_msgs; if (entry->msg_type == RADIUS_ACCT || entry->msg_type == RADIUS_ACCT_INTERIM) { + if (radius->acct_sock < 0) + radius_client_init_acct(radius); + if (radius->acct_sock < 0 && conf->num_acct_servers > 1) { + prev_num_msgs = radius->num_msgs; + radius_client_acct_failover(radius); + if (prev_num_msgs != radius->num_msgs) + return 0; + } s = radius->acct_sock; if (entry->attempts == 0) conf->acct_server->requests++; @@ -342,6 +355,14 @@ static int radius_client_retransmit(struct radius_client_data *radius, conf->acct_server->retransmissions++; } } else { + if (radius->auth_sock < 0) + radius_client_init_auth(radius); + if (radius->auth_sock < 0 && conf->num_auth_servers > 1) { + prev_num_msgs = radius->num_msgs; + radius_client_auth_failover(radius); + if (prev_num_msgs != radius->num_msgs) + return 0; + } s = radius->auth_sock; if (entry->attempts == 0) conf->auth_server->requests++; @@ -350,6 +371,11 @@ static int radius_client_retransmit(struct radius_client_data *radius, conf->auth_server->retransmissions++; } } + if (s < 0) { + wpa_printf(MSG_INFO, + "RADIUS: No valid socket for retransmission"); + return 1; + } /* retransmit; remove entry if too many attempts */ entry->attempts++; @@ -357,18 +383,20 @@ static int radius_client_retransmit(struct radius_client_data *radius, HOSTAPD_LEVEL_DEBUG, "Resending RADIUS message (id=%d)", radius_msg_get_hdr(entry->msg)->identifier); - os_get_time(&entry->last_attempt); + os_get_reltime(&entry->last_attempt); buf = radius_msg_get_buf(entry->msg); - if (send(s, wpabuf_head(buf), wpabuf_len(buf), 0) < 0) - radius_client_handle_send_error(radius, s, entry->msg_type); + if (send(s, wpabuf_head(buf), wpabuf_len(buf), 0) < 0) { + if (radius_client_handle_send_error(radius, s, entry->msg_type) + > 0) + return 0; + } entry->next_try = now + entry->next_wait; entry->next_wait *= 2; if (entry->next_wait > RADIUS_CLIENT_MAX_WAIT) entry->next_wait = RADIUS_CLIENT_MAX_WAIT; if (entry->attempts >= RADIUS_CLIENT_MAX_RETRIES) { - printf("Removing un-ACKed RADIUS message due to too many " - "failed retransmit attempts\n"); + wpa_printf(MSG_INFO, "RADIUS: Removing un-ACKed message due to too many failed retransmit attempts"); return 1; } @@ -380,21 +408,23 @@ 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_time now; + struct os_reltime now; os_time_t first; struct radius_msg_list *entry, *prev, *tmp; int auth_failover = 0, acct_failover = 0; - char abuf[50]; + size_t prev_num_msgs; + int s; entry = radius->msgs; if (!entry) return; - os_get_time(&now); + os_get_reltime(&now); first = 0; prev = NULL; while (entry) { + prev_num_msgs = radius->num_msgs; if (now.sec >= entry->next_try && radius_client_retransmit(radius, entry, now.sec)) { if (prev) @@ -409,7 +439,18 @@ static void radius_client_timer(void *eloop_ctx, void *timeout_ctx) continue; } - if (entry->attempts > RADIUS_CLIENT_NUM_FAILOVER) { + if (prev_num_msgs != radius->num_msgs) { + wpa_printf(MSG_DEBUG, + "RADIUS: Message removed from queue - restart from beginning"); + entry = radius->msgs; + prev = NULL; + continue; + } + + s = entry->msg_type == RADIUS_AUTH ? radius->auth_sock : + radius->acct_sock; + if (entry->attempts > RADIUS_CLIENT_NUM_FAILOVER || + (s < 0 && entry->attempts > 0)) { if (entry->msg_type == RADIUS_ACCT || entry->msg_type == RADIUS_ACCT_INTERIM) acct_failover++; @@ -435,60 +476,76 @@ static void radius_client_timer(void *eloop_ctx, void *timeout_ctx) (long int) (first - now.sec)); } - if (auth_failover && conf->num_auth_servers > 1) { - struct hostapd_radius_server *next, *old; - old = conf->auth_server; - hostapd_logger(radius->ctx, NULL, HOSTAPD_MODULE_RADIUS, - HOSTAPD_LEVEL_NOTICE, - "No response from Authentication server " - "%s:%d - failover", - hostapd_ip_txt(&old->addr, abuf, sizeof(abuf)), - old->port); - - for (entry = radius->msgs; entry; entry = entry->next) { - if (entry->msg_type == RADIUS_AUTH) - old->timeouts++; - } + if (auth_failover && conf->num_auth_servers > 1) + radius_client_auth_failover(radius); + + if (acct_failover && conf->num_acct_servers > 1) + radius_client_acct_failover(radius); +} - next = old + 1; - if (next > &(conf->auth_servers[conf->num_auth_servers - 1])) - next = conf->auth_servers; - conf->auth_server = next; - radius_change_server(radius, next, old, - radius->auth_serv_sock, - radius->auth_serv_sock6, 1); + +static void radius_client_auth_failover(struct radius_client_data *radius) +{ + struct hostapd_radius_servers *conf = radius->conf; + struct hostapd_radius_server *next, *old; + struct radius_msg_list *entry; + char abuf[50]; + + old = conf->auth_server; + hostapd_logger(radius->ctx, NULL, HOSTAPD_MODULE_RADIUS, + HOSTAPD_LEVEL_NOTICE, + "No response from Authentication server %s:%d - failover", + hostapd_ip_txt(&old->addr, abuf, sizeof(abuf)), + old->port); + + for (entry = radius->msgs; entry; entry = entry->next) { + if (entry->msg_type == RADIUS_AUTH) + old->timeouts++; } - if (acct_failover && conf->num_acct_servers > 1) { - struct hostapd_radius_server *next, *old; - old = conf->acct_server; - hostapd_logger(radius->ctx, NULL, HOSTAPD_MODULE_RADIUS, - HOSTAPD_LEVEL_NOTICE, - "No response from Accounting server " - "%s:%d - failover", - hostapd_ip_txt(&old->addr, abuf, sizeof(abuf)), - old->port); + next = old + 1; + if (next > &(conf->auth_servers[conf->num_auth_servers - 1])) + next = conf->auth_servers; + conf->auth_server = next; + radius_change_server(radius, next, old, + radius->auth_serv_sock, + radius->auth_serv_sock6, 1); +} - for (entry = radius->msgs; entry; entry = entry->next) { - if (entry->msg_type == RADIUS_ACCT || - entry->msg_type == RADIUS_ACCT_INTERIM) - old->timeouts++; - } - next = old + 1; - if (next > &conf->acct_servers[conf->num_acct_servers - 1]) - next = conf->acct_servers; - conf->acct_server = next; - radius_change_server(radius, next, old, - radius->acct_serv_sock, - radius->acct_serv_sock6, 0); +static void radius_client_acct_failover(struct radius_client_data *radius) +{ + struct hostapd_radius_servers *conf = radius->conf; + struct hostapd_radius_server *next, *old; + struct radius_msg_list *entry; + char abuf[50]; + + old = conf->acct_server; + hostapd_logger(radius->ctx, NULL, HOSTAPD_MODULE_RADIUS, + HOSTAPD_LEVEL_NOTICE, + "No response from Accounting server %s:%d - failover", + hostapd_ip_txt(&old->addr, abuf, sizeof(abuf)), + old->port); + + for (entry = radius->msgs; entry; entry = entry->next) { + if (entry->msg_type == RADIUS_ACCT || + entry->msg_type == RADIUS_ACCT_INTERIM) + old->timeouts++; } + + next = old + 1; + if (next > &conf->acct_servers[conf->num_acct_servers - 1]) + next = conf->acct_servers; + conf->acct_server = next; + radius_change_server(radius, next, old, + radius->acct_serv_sock, + radius->acct_serv_sock6, 0); } static void radius_client_update_timeout(struct radius_client_data *radius) { - struct os_time now; + struct os_reltime now; os_time_t first; struct radius_msg_list *entry; @@ -504,14 +561,14 @@ static void radius_client_update_timeout(struct radius_client_data *radius) first = entry->next_try; } - os_get_time(&now); + os_get_reltime(&now); if (first < now.sec) first = now.sec; eloop_register_timeout(first - now.sec, 0, radius_client_timer, radius, NULL); hostapd_logger(radius->ctx, NULL, HOSTAPD_MODULE_RADIUS, HOSTAPD_LEVEL_DEBUG, "Next RADIUS client retransmit in" - " %ld seconds\n", (long int) (first - now.sec)); + " %ld seconds", (long int) (first - now.sec)); } @@ -532,7 +589,7 @@ static void radius_client_list_add(struct radius_client_data *radius, entry = os_zalloc(sizeof(*entry)); if (entry == NULL) { - printf("Failed to add RADIUS packet into retransmit list\n"); + wpa_printf(MSG_INFO, "RADIUS: Failed to add packet into retransmit list"); radius_msg_free(msg); return; } @@ -543,7 +600,7 @@ static void radius_client_list_add(struct radius_client_data *radius, entry->msg_type = msg_type; entry->shared_secret = shared_secret; entry->shared_secret_len = shared_secret_len; - os_get_time(&entry->last_attempt); + os_get_reltime(&entry->last_attempt); entry->first_try = entry->last_attempt.sec; entry->next_try = entry->first_try + RADIUS_CLIENT_FIRST_WAIT; entry->attempts = 1; @@ -553,8 +610,7 @@ static void radius_client_list_add(struct radius_client_data *radius, radius_client_update_timeout(radius); if (radius->num_msgs >= RADIUS_CLIENT_MAX_ENTRIES) { - printf("Removing the oldest un-ACKed RADIUS packet due to " - "retransmit list limits.\n"); + wpa_printf(MSG_INFO, "RADIUS: Removing the oldest un-ACKed packet due to retransmit list limits"); prev = NULL; while (entry->next) { prev = entry; @@ -641,7 +697,11 @@ int radius_client_send(struct radius_client_data *radius, } if (msg_type == RADIUS_ACCT || msg_type == RADIUS_ACCT_INTERIM) { - if (conf->acct_server == NULL) { + if (conf->acct_server && radius->acct_sock < 0) + radius_client_init_acct(radius); + + if (conf->acct_server == NULL || radius->acct_sock < 0 || + conf->acct_server->shared_secret == NULL) { hostapd_logger(radius->ctx, NULL, HOSTAPD_MODULE_RADIUS, HOSTAPD_LEVEL_INFO, @@ -655,7 +715,11 @@ int radius_client_send(struct radius_client_data *radius, s = radius->acct_sock; conf->acct_server->requests++; } else { - if (conf->auth_server == NULL) { + if (conf->auth_server && radius->auth_sock < 0) + radius_client_init_auth(radius); + + if (conf->auth_server == NULL || radius->auth_sock < 0 || + conf->auth_server->shared_secret == NULL) { hostapd_logger(radius->ctx, NULL, HOSTAPD_MODULE_RADIUS, HOSTAPD_LEVEL_INFO, @@ -684,7 +748,7 @@ int radius_client_send(struct radius_client_data *radius, radius_client_list_add(radius, msg, msg_type, shared_secret, shared_secret_len, addr); - return res; + return 0; } @@ -700,7 +764,7 @@ static void radius_client_receive(int sock, void *eloop_ctx, void *sock_ctx) struct radius_rx_handler *handlers; size_t num_handlers, i; struct radius_msg_list *req, *prev_req; - struct os_time now; + struct os_reltime now; struct hostapd_radius_server *rconf; int invalid_authenticator = 0; @@ -716,21 +780,20 @@ static void radius_client_receive(int sock, void *eloop_ctx, void *sock_ctx) len = recv(sock, buf, sizeof(buf), MSG_DONTWAIT); if (len < 0) { - perror("recv[RADIUS]"); + wpa_printf(MSG_INFO, "recv[RADIUS]: %s", strerror(errno)); return; } hostapd_logger(radius->ctx, NULL, HOSTAPD_MODULE_RADIUS, HOSTAPD_LEVEL_DEBUG, "Received %d bytes from RADIUS " "server", len); if (len == sizeof(buf)) { - printf("Possibly too long UDP frame for our buffer - " - "dropping it\n"); + wpa_printf(MSG_INFO, "RADIUS: Possibly too long UDP frame for our buffer - dropping it"); return; } msg = radius_msg_parse(buf, len); if (msg == NULL) { - printf("Parsing incoming RADIUS frame failed\n"); + wpa_printf(MSG_INFO, "RADIUS: Parsing incoming frame failed"); rconf->malformed_responses++; return; } @@ -781,7 +844,7 @@ static void radius_client_receive(int sock, void *eloop_ctx, void *sock_ctx) goto fail; } - os_get_time(&now); + os_get_reltime(&now); roundtrip = (now.sec - req->last_attempt.sec) * 100 + (now.usec - req->last_attempt.usec) / 10000; hostapd_logger(radius->ctx, req->addr, HOSTAPD_MODULE_RADIUS, @@ -960,9 +1023,10 @@ radius_change_server(struct radius_client_data *radius, hostapd_ip_txt(&nserv->addr, abuf, sizeof(abuf)), nserv->port); - if (!oserv || nserv->shared_secret_len != oserv->shared_secret_len || - os_memcmp(nserv->shared_secret, oserv->shared_secret, - nserv->shared_secret_len) != 0) { + if (oserv && oserv != nserv && + (nserv->shared_secret_len != oserv->shared_secret_len || + os_memcmp(nserv->shared_secret, oserv->shared_secret, + nserv->shared_secret_len) != 0)) { /* Pending RADIUS packets used different shared secret, so * they need to be modified. Update accounting message * authenticators here. Authentication messages are removed @@ -980,7 +1044,8 @@ radius_change_server(struct radius_client_data *radius, } /* Reset retry counters for the new server */ - for (entry = radius->msgs; entry; entry = entry->next) { + for (entry = radius->msgs; oserv && oserv != nserv && entry; + entry = entry->next) { if ((auth && entry->msg_type != RADIUS_AUTH) || (!auth && entry->msg_type != RADIUS_ACCT)) continue; @@ -1021,6 +1086,13 @@ radius_change_server(struct radius_client_data *radius, return -1; } + if (sel_sock < 0) { + wpa_printf(MSG_INFO, + "RADIUS: No server socket available (af=%d sock=%d sock6=%d auth=%d", + nserv->addr.af, sock, sock6, auth); + return -1; + } + if (conf->force_client_addr) { switch (conf->client_addr.af) { case AF_INET: @@ -1047,13 +1119,14 @@ radius_change_server(struct radius_client_data *radius, } if (bind(sel_sock, cl_addr, claddrlen) < 0) { - perror("bind[radius]"); + wpa_printf(MSG_INFO, "bind[radius]: %s", + strerror(errno)); return -1; } } if (connect(sel_sock, addr, addrlen) < 0) { - perror("connect[radius]"); + wpa_printf(MSG_INFO, "connect[radius]: %s", strerror(errno)); return -1; } @@ -1061,19 +1134,23 @@ radius_change_server(struct radius_client_data *radius, switch (nserv->addr.af) { case AF_INET: claddrlen = sizeof(claddr); - getsockname(sel_sock, (struct sockaddr *) &claddr, &claddrlen); - wpa_printf(MSG_DEBUG, "RADIUS local address: %s:%u", - inet_ntoa(claddr.sin_addr), ntohs(claddr.sin_port)); + if (getsockname(sel_sock, (struct sockaddr *) &claddr, + &claddrlen) == 0) { + wpa_printf(MSG_DEBUG, "RADIUS local address: %s:%u", + inet_ntoa(claddr.sin_addr), + ntohs(claddr.sin_port)); + } break; #ifdef CONFIG_IPV6 case AF_INET6: { claddrlen = sizeof(claddr6); - getsockname(sel_sock, (struct sockaddr *) &claddr6, - &claddrlen); - wpa_printf(MSG_DEBUG, "RADIUS local address: %s:%u", - inet_ntop(AF_INET6, &claddr6.sin6_addr, - abuf, sizeof(abuf)), - ntohs(claddr6.sin6_port)); + if (getsockname(sel_sock, (struct sockaddr *) &claddr6, + &claddrlen) == 0) { + wpa_printf(MSG_DEBUG, "RADIUS local address: %s:%u", + inet_ntop(AF_INET6, &claddr6.sin6_addr, + abuf, sizeof(abuf)), + ntohs(claddr6.sin6_port)); + } break; } #endif /* CONFIG_IPV6 */ @@ -1099,18 +1176,28 @@ static void radius_retry_primary_timer(void *eloop_ctx, void *timeout_ctx) conf->auth_server != conf->auth_servers) { oserv = conf->auth_server; conf->auth_server = conf->auth_servers; - radius_change_server(radius, conf->auth_server, oserv, - radius->auth_serv_sock, - radius->auth_serv_sock6, 1); + if (radius_change_server(radius, conf->auth_server, oserv, + radius->auth_serv_sock, + radius->auth_serv_sock6, 1) < 0) { + conf->auth_server = oserv; + radius_change_server(radius, oserv, conf->auth_server, + radius->auth_serv_sock, + radius->auth_serv_sock6, 1); + } } if (radius->acct_sock >= 0 && conf->acct_servers && conf->acct_server != conf->acct_servers) { oserv = conf->acct_server; conf->acct_server = conf->acct_servers; - radius_change_server(radius, conf->acct_server, oserv, - radius->acct_serv_sock, - radius->acct_serv_sock6, 0); + if (radius_change_server(radius, conf->acct_server, oserv, + radius->acct_serv_sock, + radius->acct_serv_sock6, 0) < 0) { + conf->acct_server = oserv; + radius_change_server(radius, oserv, conf->acct_server, + radius->acct_serv_sock, + radius->acct_serv_sock6, 0); + } } if (conf->retry_primary_interval) @@ -1129,21 +1216,62 @@ static int radius_client_disable_pmtu_discovery(int s) r = setsockopt(s, IPPROTO_IP, IP_MTU_DISCOVER, &action, sizeof(action)); if (r == -1) - wpa_printf(MSG_ERROR, "Failed to set IP_MTU_DISCOVER: " - "%s", strerror(errno)); + wpa_printf(MSG_ERROR, "RADIUS: Failed to set IP_MTU_DISCOVER: %s", + strerror(errno)); #endif return r; } +static void radius_close_auth_sockets(struct radius_client_data *radius) +{ + radius->auth_sock = -1; + + if (radius->auth_serv_sock >= 0) { + eloop_unregister_read_sock(radius->auth_serv_sock); + close(radius->auth_serv_sock); + radius->auth_serv_sock = -1; + } +#ifdef CONFIG_IPV6 + if (radius->auth_serv_sock6 >= 0) { + eloop_unregister_read_sock(radius->auth_serv_sock6); + close(radius->auth_serv_sock6); + radius->auth_serv_sock6 = -1; + } +#endif /* CONFIG_IPV6 */ +} + + +static void radius_close_acct_sockets(struct radius_client_data *radius) +{ + radius->acct_sock = -1; + + if (radius->acct_serv_sock >= 0) { + eloop_unregister_read_sock(radius->acct_serv_sock); + close(radius->acct_serv_sock); + radius->acct_serv_sock = -1; + } +#ifdef CONFIG_IPV6 + if (radius->acct_serv_sock6 >= 0) { + eloop_unregister_read_sock(radius->acct_serv_sock6); + close(radius->acct_serv_sock6); + radius->acct_serv_sock6 = -1; + } +#endif /* CONFIG_IPV6 */ +} + + static int radius_client_init_auth(struct radius_client_data *radius) { struct hostapd_radius_servers *conf = radius->conf; int ok = 0; + radius_close_auth_sockets(radius); + radius->auth_serv_sock = socket(PF_INET, SOCK_DGRAM, 0); if (radius->auth_serv_sock < 0) - perror("socket[PF_INET,SOCK_DGRAM]"); + wpa_printf(MSG_INFO, "RADIUS: socket[PF_INET,SOCK_DGRAM]: %s", + strerror(errno)); else { radius_client_disable_pmtu_discovery(radius->auth_serv_sock); ok++; @@ -1152,7 +1280,8 @@ static int radius_client_init_auth(struct radius_client_data *radius) #ifdef CONFIG_IPV6 radius->auth_serv_sock6 = socket(PF_INET6, SOCK_DGRAM, 0); if (radius->auth_serv_sock6 < 0) - perror("socket[PF_INET6,SOCK_DGRAM]"); + wpa_printf(MSG_INFO, "RADIUS: socket[PF_INET6,SOCK_DGRAM]: %s", + strerror(errno)); else ok++; #endif /* CONFIG_IPV6 */ @@ -1168,8 +1297,8 @@ static int radius_client_init_auth(struct radius_client_data *radius) eloop_register_read_sock(radius->auth_serv_sock, radius_client_receive, radius, (void *) RADIUS_AUTH)) { - printf("Could not register read socket for authentication " - "server\n"); + wpa_printf(MSG_INFO, "RADIUS: Could not register read socket for authentication server"); + radius_close_auth_sockets(radius); return -1; } @@ -1178,8 +1307,8 @@ static int radius_client_init_auth(struct radius_client_data *radius) eloop_register_read_sock(radius->auth_serv_sock6, radius_client_receive, radius, (void *) RADIUS_AUTH)) { - printf("Could not register read socket for authentication " - "server\n"); + wpa_printf(MSG_INFO, "RADIUS: Could not register read socket for authentication server"); + radius_close_auth_sockets(radius); return -1; } #endif /* CONFIG_IPV6 */ @@ -1193,9 +1322,12 @@ static int radius_client_init_acct(struct radius_client_data *radius) struct hostapd_radius_servers *conf = radius->conf; int ok = 0; + radius_close_acct_sockets(radius); + radius->acct_serv_sock = socket(PF_INET, SOCK_DGRAM, 0); if (radius->acct_serv_sock < 0) - perror("socket[PF_INET,SOCK_DGRAM]"); + wpa_printf(MSG_INFO, "RADIUS: socket[PF_INET,SOCK_DGRAM]: %s", + strerror(errno)); else { radius_client_disable_pmtu_discovery(radius->acct_serv_sock); ok++; @@ -1204,7 +1336,8 @@ static int radius_client_init_acct(struct radius_client_data *radius) #ifdef CONFIG_IPV6 radius->acct_serv_sock6 = socket(PF_INET6, SOCK_DGRAM, 0); if (radius->acct_serv_sock6 < 0) - perror("socket[PF_INET6,SOCK_DGRAM]"); + wpa_printf(MSG_INFO, "RADIUS: socket[PF_INET6,SOCK_DGRAM]: %s", + strerror(errno)); else ok++; #endif /* CONFIG_IPV6 */ @@ -1220,8 +1353,8 @@ static int radius_client_init_acct(struct radius_client_data *radius) eloop_register_read_sock(radius->acct_serv_sock, radius_client_receive, radius, (void *) RADIUS_ACCT)) { - printf("Could not register read socket for accounting " - "server\n"); + wpa_printf(MSG_INFO, "RADIUS: Could not register read socket for accounting server"); + radius_close_acct_sockets(radius); return -1; } @@ -1230,8 +1363,8 @@ static int radius_client_init_acct(struct radius_client_data *radius) eloop_register_read_sock(radius->acct_serv_sock6, radius_client_receive, radius, (void *) RADIUS_ACCT)) { - printf("Could not register read socket for accounting " - "server\n"); + wpa_printf(MSG_INFO, "RADIUS: Could not register read socket for accounting server"); + radius_close_acct_sockets(radius); return -1; } #endif /* CONFIG_IPV6 */ @@ -1293,16 +1426,8 @@ void radius_client_deinit(struct radius_client_data *radius) if (!radius) return; - if (radius->auth_serv_sock >= 0) - eloop_unregister_read_sock(radius->auth_serv_sock); - if (radius->acct_serv_sock >= 0) - eloop_unregister_read_sock(radius->acct_serv_sock); -#ifdef CONFIG_IPV6 - if (radius->auth_serv_sock6 >= 0) - eloop_unregister_read_sock(radius->auth_serv_sock6); - if (radius->acct_serv_sock6 >= 0) - eloop_unregister_read_sock(radius->acct_serv_sock6); -#endif /* CONFIG_IPV6 */ + radius_close_auth_sockets(radius); + radius_close_acct_sockets(radius); eloop_cancel_timeout(radius_retry_primary_timer, radius, NULL); @@ -1489,3 +1614,11 @@ int radius_client_get_mib(struct radius_client_data *radius, char *buf, return count; } + + +void radius_client_reconfig(struct radius_client_data *radius, + struct hostapd_radius_servers *conf) +{ + if (radius) + radius->conf = conf; +}