Home | History | Annotate | Line # | Download | only in radius
      1 /*
      2  * RADIUS client
      3  * Copyright (c) 2002-2024, Jouni Malinen <j (at) w1.fi>
      4  *
      5  * This software may be distributed under the terms of the BSD license.
      6  * See README for more details.
      7  */
      8 
      9 #include "includes.h"
     10 #include <fcntl.h>
     11 #include <net/if.h>
     12 
     13 #include "common.h"
     14 #include "eloop.h"
     15 #include "crypto/tls.h"
     16 #include "radius.h"
     17 #include "radius_client.h"
     18 
     19 /* Defaults for RADIUS retransmit values (exponential backoff) */
     20 
     21 /**
     22  * RADIUS_CLIENT_FIRST_WAIT - RADIUS client timeout for first retry in seconds
     23  */
     24 #define RADIUS_CLIENT_FIRST_WAIT 3
     25 
     26 /**
     27  * RADIUS_CLIENT_MAX_WAIT - RADIUS client maximum retry timeout in seconds
     28  */
     29 #define RADIUS_CLIENT_MAX_WAIT 120
     30 
     31 /**
     32  * RADIUS_CLIENT_MAX_FAILOVER - RADIUS client maximum retries
     33  *
     34  * Maximum number of server failovers before the entry is removed from
     35  * retransmit list.
     36  */
     37 #define RADIUS_CLIENT_MAX_FAILOVER 3
     38 
     39 /**
     40  * RADIUS_CLIENT_MAX_ENTRIES - RADIUS client maximum pending messages
     41  *
     42  * Maximum number of entries in retransmit list (oldest entries will be
     43  * removed, if this limit is exceeded).
     44  */
     45 #define RADIUS_CLIENT_MAX_ENTRIES 30
     46 
     47 /**
     48  * RADIUS_CLIENT_NUM_FAILOVER - RADIUS client failover point
     49  *
     50  * The number of failed retry attempts after which the RADIUS server will be
     51  * changed (if one of more backup servers are configured).
     52  */
     53 #define RADIUS_CLIENT_NUM_FAILOVER 4
     54 
     55 
     56 /**
     57  * struct radius_rx_handler - RADIUS client RX handler
     58  *
     59  * This data structure is used internally inside the RADIUS client module to
     60  * store registered RX handlers. These handlers are registered by calls to
     61  * radius_client_register() and unregistered when the RADIUS client is
     62  * deinitialized with a call to radius_client_deinit().
     63  */
     64 struct radius_rx_handler {
     65 	/**
     66 	 * handler - Received RADIUS message handler
     67 	 */
     68 	RadiusRxResult (*handler)(struct radius_msg *msg,
     69 				  struct radius_msg *req,
     70 				  const u8 *shared_secret,
     71 				  size_t shared_secret_len,
     72 				  void *data);
     73 
     74 	/**
     75 	 * data - Context data for the handler
     76 	 */
     77 	void *data;
     78 };
     79 
     80 
     81 /**
     82  * struct radius_msg_list - RADIUS client message retransmit list
     83  *
     84  * This data structure is used internally inside the RADIUS client module to
     85  * store pending RADIUS requests that may still need to be retransmitted.
     86  */
     87 struct radius_msg_list {
     88 	/**
     89 	 * addr - STA/client address
     90 	 *
     91 	 * This is used to find RADIUS messages for the same STA.
     92 	 */
     93 	u8 addr[ETH_ALEN];
     94 
     95 	/**
     96 	 * msg - RADIUS message
     97 	 */
     98 	struct radius_msg *msg;
     99 
    100 	/**
    101 	 * msg_type - Message type
    102 	 */
    103 	RadiusType msg_type;
    104 
    105 	/**
    106 	 * first_try - Time of the first transmission attempt
    107 	 */
    108 	os_time_t first_try;
    109 
    110 	/**
    111 	 * next_try - Time for the next transmission attempt
    112 	 */
    113 	os_time_t next_try;
    114 
    115 	/**
    116 	 * attempts - Number of transmission attempts for one server
    117 	 */
    118 	int attempts;
    119 
    120 	/**
    121 	 * accu_attempts - Number of accumulated attempts
    122 	 */
    123 	int accu_attempts;
    124 
    125 	/**
    126 	 * next_wait - Next retransmission wait time in seconds
    127 	 */
    128 	int next_wait;
    129 
    130 	/**
    131 	 * last_attempt - Time of the last transmission attempt
    132 	 */
    133 	struct os_reltime last_attempt;
    134 
    135 	/**
    136 	 * shared_secret - Shared secret with the target RADIUS server
    137 	 */
    138 	const u8 *shared_secret;
    139 
    140 	/**
    141 	 * shared_secret_len - shared_secret length in octets
    142 	 */
    143 	size_t shared_secret_len;
    144 
    145 	/* TODO: server config with failover to backup server(s) */
    146 
    147 	/**
    148 	 * next - Next message in the list
    149 	 */
    150 	struct radius_msg_list *next;
    151 };
    152 
    153 
    154 /**
    155  * struct radius_client_data - Internal RADIUS client data
    156  *
    157  * This data structure is used internally inside the RADIUS client module.
    158  * External users allocate this by calling radius_client_init() and free it by
    159  * calling radius_client_deinit(). The pointer to this opaque data is used in
    160  * calls to other functions as an identifier for the RADIUS client instance.
    161  */
    162 struct radius_client_data {
    163 	/**
    164 	 * ctx - Context pointer for hostapd_logger() callbacks
    165 	 */
    166 	void *ctx;
    167 
    168 	/**
    169 	 * conf - RADIUS client configuration (list of RADIUS servers to use)
    170 	 */
    171 	struct hostapd_radius_servers *conf;
    172 
    173 	/**
    174 	 * auth_sock - Currently used socket for RADIUS authentication server
    175 	 */
    176 	int auth_sock;
    177 
    178 	/**
    179 	 * auth_tls - Whether current authentication connection uses TLS
    180 	 */
    181 	bool auth_tls;
    182 
    183 	/**
    184 	 * auth_tls_ready - Whether authentication TLS is ready
    185 	 */
    186 	bool auth_tls_ready;
    187 
    188 	/**
    189 	 * acct_sock - Currently used socket for RADIUS accounting server
    190 	 */
    191 	int acct_sock;
    192 
    193 	/**
    194 	 * acct_tls - Whether current accounting connection uses TLS
    195 	 */
    196 	bool acct_tls;
    197 
    198 	/**
    199 	 * acct_tls_ready - Whether accounting TLS is ready
    200 	 */
    201 	bool acct_tls_ready;
    202 
    203 	/**
    204 	 * auth_handlers - Authentication message handlers
    205 	 */
    206 	struct radius_rx_handler *auth_handlers;
    207 
    208 	/**
    209 	 * num_auth_handlers - Number of handlers in auth_handlers
    210 	 */
    211 	size_t num_auth_handlers;
    212 
    213 	/**
    214 	 * acct_handlers - Accounting message handlers
    215 	 */
    216 	struct radius_rx_handler *acct_handlers;
    217 
    218 	/**
    219 	 * num_acct_handlers - Number of handlers in acct_handlers
    220 	 */
    221 	size_t num_acct_handlers;
    222 
    223 	/**
    224 	 * msgs - Pending outgoing RADIUS messages
    225 	 */
    226 	struct radius_msg_list *msgs;
    227 
    228 	/**
    229 	 * num_msgs - Number of pending messages in the msgs list
    230 	 */
    231 	size_t num_msgs;
    232 
    233 	/**
    234 	 * next_radius_identifier - Next RADIUS message identifier to use
    235 	 */
    236 	u8 next_radius_identifier;
    237 
    238 	/**
    239 	 * interim_error_cb - Interim accounting error callback
    240 	 */
    241 	void (*interim_error_cb)(const u8 *addr, void *ctx);
    242 
    243 	/**
    244 	 * interim_error_cb_ctx - interim_error_cb() context data
    245 	 */
    246 	void *interim_error_cb_ctx;
    247 
    248 #ifdef CONFIG_RADIUS_TLS
    249 	void *tls_ctx;
    250 	struct tls_connection *auth_tls_conn;
    251 	struct tls_connection *acct_tls_conn;
    252 #endif /* CONFIG_RADIUS_TLS */
    253 };
    254 
    255 
    256 static int
    257 radius_change_server(struct radius_client_data *radius,
    258 		     struct hostapd_radius_server *nserv,
    259 		     struct hostapd_radius_server *oserv,
    260 		     int auth);
    261 static int radius_client_init_acct(struct radius_client_data *radius);
    262 static int radius_client_init_auth(struct radius_client_data *radius);
    263 static void radius_client_auth_failover(struct radius_client_data *radius);
    264 static void radius_client_acct_failover(struct radius_client_data *radius);
    265 
    266 
    267 static void radius_client_msg_free(struct radius_msg_list *req)
    268 {
    269 	radius_msg_free(req->msg);
    270 	os_free(req);
    271 }
    272 
    273 
    274 /**
    275  * radius_client_register - Register a RADIUS client RX handler
    276  * @radius: RADIUS client context from radius_client_init()
    277  * @msg_type: RADIUS client type (RADIUS_AUTH or RADIUS_ACCT)
    278  * @handler: Handler for received RADIUS messages
    279  * @data: Context pointer for handler callbacks
    280  * Returns: 0 on success, -1 on failure
    281  *
    282  * This function is used to register a handler for processing received RADIUS
    283  * authentication and accounting messages. The handler() callback function will
    284  * be called whenever a RADIUS message is received from the active server.
    285  *
    286  * There can be multiple registered RADIUS message handlers. The handlers will
    287  * be called in order until one of them indicates that it has processed or
    288  * queued the message.
    289  */
    290 int radius_client_register(struct radius_client_data *radius,
    291 			   RadiusType msg_type,
    292 			   RadiusRxResult (*handler)(struct radius_msg *msg,
    293 						     struct radius_msg *req,
    294 						     const u8 *shared_secret,
    295 						     size_t shared_secret_len,
    296 						     void *data),
    297 			   void *data)
    298 {
    299 	struct radius_rx_handler **handlers, *newh;
    300 	size_t *num;
    301 
    302 	if (msg_type == RADIUS_ACCT) {
    303 		handlers = &radius->acct_handlers;
    304 		num = &radius->num_acct_handlers;
    305 	} else {
    306 		handlers = &radius->auth_handlers;
    307 		num = &radius->num_auth_handlers;
    308 	}
    309 
    310 	newh = os_realloc_array(*handlers, *num + 1,
    311 				sizeof(struct radius_rx_handler));
    312 	if (newh == NULL)
    313 		return -1;
    314 
    315 	newh[*num].handler = handler;
    316 	newh[*num].data = data;
    317 	(*num)++;
    318 	*handlers = newh;
    319 
    320 	return 0;
    321 }
    322 
    323 
    324 /**
    325  * radius_client_set_interim_erro_cb - Register an interim acct error callback
    326  * @radius: RADIUS client context from radius_client_init()
    327  * @addr: Station address from the failed message
    328  * @cb: Handler for interim accounting errors
    329  * @ctx: Context pointer for handler callbacks
    330  *
    331  * This function is used to register a handler for processing failed
    332  * transmission attempts of interim accounting update messages.
    333  */
    334 void radius_client_set_interim_error_cb(struct radius_client_data *radius,
    335 					void (*cb)(const u8 *addr, void *ctx),
    336 					void *ctx)
    337 {
    338 	radius->interim_error_cb = cb;
    339 	radius->interim_error_cb_ctx = ctx;
    340 }
    341 
    342 
    343 /*
    344  * Returns >0 if message queue was flushed (i.e., the message that triggered
    345  * the error is not available anymore)
    346  */
    347 static int radius_client_handle_send_error(struct radius_client_data *radius,
    348 					   int s, RadiusType msg_type)
    349 {
    350 #ifndef CONFIG_NATIVE_WINDOWS
    351 	int _errno = errno;
    352 	wpa_printf(MSG_INFO, "send[RADIUS,s=%d]: %s", s, strerror(errno));
    353 	if (_errno == ENOTCONN || _errno == EDESTADDRREQ || _errno == EINVAL ||
    354 	    _errno == EBADF || _errno == ENETUNREACH || _errno == EACCES) {
    355 		hostapd_logger(radius->ctx, NULL, HOSTAPD_MODULE_RADIUS,
    356 			       HOSTAPD_LEVEL_INFO,
    357 			       "Send failed - maybe interface status changed -"
    358 			       " try to connect again");
    359 		if (msg_type == RADIUS_ACCT ||
    360 		    msg_type == RADIUS_ACCT_INTERIM) {
    361 			radius_client_init_acct(radius);
    362 			return 0;
    363 		} else {
    364 			radius_client_init_auth(radius);
    365 			return 1;
    366 		}
    367 	}
    368 #endif /* CONFIG_NATIVE_WINDOWS */
    369 
    370 	return 0;
    371 }
    372 
    373 
    374 static int radius_client_retransmit(struct radius_client_data *radius,
    375 				    struct radius_msg_list *entry,
    376 				    os_time_t now)
    377 {
    378 	struct hostapd_radius_servers *conf = radius->conf;
    379 	int s;
    380 	struct wpabuf *buf;
    381 	size_t prev_num_msgs;
    382 	u8 *acct_delay_time;
    383 	size_t acct_delay_time_len;
    384 	int num_servers;
    385 #ifdef CONFIG_RADIUS_TLS
    386 	struct wpabuf *out = NULL;
    387 	struct tls_connection *conn = NULL;
    388 	bool acct = false;
    389 #endif /* CONFIG_RADIUS_TLS */
    390 
    391 	if (entry->msg_type == RADIUS_ACCT ||
    392 	    entry->msg_type == RADIUS_ACCT_INTERIM) {
    393 #ifdef CONFIG_RADIUS_TLS
    394 		acct = true;
    395 		if (radius->acct_tls)
    396 			conn = radius->acct_tls_conn;
    397 #endif /* CONFIG_RADIUS_TLS */
    398 		num_servers = conf->num_acct_servers;
    399 		if (radius->acct_sock < 0)
    400 			radius_client_init_acct(radius);
    401 		if (radius->acct_sock < 0 && conf->num_acct_servers > 1) {
    402 			prev_num_msgs = radius->num_msgs;
    403 			radius_client_acct_failover(radius);
    404 			if (prev_num_msgs != radius->num_msgs)
    405 				return 0;
    406 		}
    407 		s = radius->acct_sock;
    408 		if (entry->attempts == 0)
    409 			conf->acct_server->requests++;
    410 		else {
    411 			conf->acct_server->timeouts++;
    412 			conf->acct_server->retransmissions++;
    413 		}
    414 	} else {
    415 #ifdef CONFIG_RADIUS_TLS
    416 		if (radius->auth_tls)
    417 			conn = radius->auth_tls_conn;
    418 #endif /* CONFIG_RADIUS_TLS */
    419 		num_servers = conf->num_auth_servers;
    420 		if (radius->auth_sock < 0)
    421 			radius_client_init_auth(radius);
    422 		if (radius->auth_sock < 0 && conf->num_auth_servers > 1) {
    423 			prev_num_msgs = radius->num_msgs;
    424 			radius_client_auth_failover(radius);
    425 			if (prev_num_msgs != radius->num_msgs)
    426 				return 0;
    427 		}
    428 		s = radius->auth_sock;
    429 		if (entry->attempts == 0)
    430 			conf->auth_server->requests++;
    431 		else {
    432 			conf->auth_server->timeouts++;
    433 			conf->auth_server->retransmissions++;
    434 		}
    435 	}
    436 
    437 	if (entry->msg_type == RADIUS_ACCT_INTERIM) {
    438 		wpa_printf(MSG_DEBUG,
    439 			   "RADIUS: Failed to transmit interim accounting update to "
    440 			   MACSTR " - drop message and request a new update",
    441 			   MAC2STR(entry->addr));
    442 		if (radius->interim_error_cb)
    443 			radius->interim_error_cb(entry->addr,
    444 						 radius->interim_error_cb_ctx);
    445 		return 1;
    446 	}
    447 
    448 	if (s < 0) {
    449 		wpa_printf(MSG_INFO,
    450 			   "RADIUS: No valid socket for retransmission");
    451 		return 1;
    452 	}
    453 
    454 #ifdef CONFIG_RADIUS_TLS
    455 	if ((acct && radius->acct_tls && !radius->acct_tls_ready) ||
    456 	    (!acct && radius->auth_tls && !radius->auth_tls_ready)) {
    457 		wpa_printf(MSG_DEBUG,
    458 			   "RADIUS: TLS connection not yet ready for TX");
    459 		goto not_ready;
    460 	}
    461 #endif /* CONFIG_RADIUS_TLS */
    462 
    463 	if (entry->msg_type == RADIUS_ACCT &&
    464 	    radius_msg_get_attr_ptr(entry->msg, RADIUS_ATTR_ACCT_DELAY_TIME,
    465 				    &acct_delay_time, &acct_delay_time_len,
    466 				    NULL) == 0 &&
    467 	    acct_delay_time_len == 4) {
    468 		struct radius_hdr *hdr;
    469 		u32 delay_time;
    470 
    471 		/*
    472 		 * Need to assign a new identifier since attribute contents
    473 		 * changes.
    474 		 */
    475 		hdr = radius_msg_get_hdr(entry->msg);
    476 		hdr->identifier = radius_client_get_id(radius);
    477 
    478 		/* Update Acct-Delay-Time to show wait time in queue */
    479 		delay_time = now - entry->first_try;
    480 		WPA_PUT_BE32(acct_delay_time, delay_time);
    481 
    482 		wpa_printf(MSG_DEBUG,
    483 			   "RADIUS: Updated Acct-Delay-Time to %u for retransmission",
    484 			   delay_time);
    485 		radius_msg_finish_acct(entry->msg, entry->shared_secret,
    486 				       entry->shared_secret_len);
    487 		if (radius->conf->msg_dumps)
    488 			radius_msg_dump(entry->msg);
    489 	}
    490 
    491 	/* retransmit; remove entry if too many attempts */
    492 	if (entry->accu_attempts >= RADIUS_CLIENT_MAX_FAILOVER *
    493 	    RADIUS_CLIENT_NUM_FAILOVER * num_servers) {
    494 		wpa_printf(MSG_INFO,
    495 			   "RADIUS: Removing un-ACKed message due to too many failed retransmit attempts");
    496 		return 1;
    497 	}
    498 
    499 	entry->attempts++;
    500 	entry->accu_attempts++;
    501 	hostapd_logger(radius->ctx, entry->addr, HOSTAPD_MODULE_RADIUS,
    502 		       HOSTAPD_LEVEL_DEBUG, "Resending RADIUS message (id=%d)",
    503 		       radius_msg_get_hdr(entry->msg)->identifier);
    504 
    505 	os_get_reltime(&entry->last_attempt);
    506 	buf = radius_msg_get_buf(entry->msg);
    507 #ifdef CONFIG_RADIUS_TLS
    508 	if (conn) {
    509 		out = tls_connection_encrypt(radius->tls_ctx, conn, buf);
    510 		if (!out) {
    511 			wpa_printf(MSG_INFO,
    512 				   "RADIUS: Failed to encrypt RADIUS message (TLS)");
    513 			return -1;
    514 		}
    515 		wpa_printf(MSG_DEBUG,
    516 			   "RADIUS: TLS encryption of %zu bytes of plaintext to %zu bytes of ciphertext",
    517 			   wpabuf_len(buf), wpabuf_len(out));
    518 		buf = out;
    519 	}
    520 #endif /* CONFIG_RADIUS_TLS */
    521 
    522 	wpa_printf(MSG_DEBUG, "RADIUS: Send %zu bytes to the server",
    523 		   wpabuf_len(buf));
    524 	if (send(s, wpabuf_head(buf), wpabuf_len(buf), 0) < 0) {
    525 		if (radius_client_handle_send_error(radius, s, entry->msg_type)
    526 		    > 0) {
    527 #ifdef CONFIG_RADIUS_TLS
    528 			wpabuf_free(out);
    529 #endif /* CONFIG_RADIUS_TLS */
    530 			return 0;
    531 		}
    532 	}
    533 #ifdef CONFIG_RADIUS_TLS
    534 	wpabuf_free(out);
    535 
    536 not_ready:
    537 #endif /* CONFIG_RADIUS_TLS */
    538 
    539 	entry->next_try = now + entry->next_wait;
    540 	entry->next_wait *= 2;
    541 	if (entry->next_wait > RADIUS_CLIENT_MAX_WAIT)
    542 		entry->next_wait = RADIUS_CLIENT_MAX_WAIT;
    543 
    544 	return 0;
    545 }
    546 
    547 
    548 static void radius_client_timer(void *eloop_ctx, void *timeout_ctx)
    549 {
    550 	struct radius_client_data *radius = eloop_ctx;
    551 	struct os_reltime now;
    552 	os_time_t first;
    553 	struct radius_msg_list *entry, *prev, *tmp;
    554 	int auth_failover = 0, acct_failover = 0;
    555 	size_t prev_num_msgs;
    556 	int s;
    557 
    558 	entry = radius->msgs;
    559 	if (!entry)
    560 		return;
    561 
    562 	os_get_reltime(&now);
    563 
    564 	while (entry) {
    565 		if (now.sec >= entry->next_try) {
    566 			s = entry->msg_type == RADIUS_AUTH ? radius->auth_sock :
    567 				radius->acct_sock;
    568 			if (entry->attempts >= RADIUS_CLIENT_NUM_FAILOVER ||
    569 			    (s < 0 && entry->attempts > 0)) {
    570 				if (entry->msg_type == RADIUS_ACCT ||
    571 				    entry->msg_type == RADIUS_ACCT_INTERIM)
    572 					acct_failover++;
    573 				else
    574 					auth_failover++;
    575 			}
    576 		}
    577 		entry = entry->next;
    578 	}
    579 
    580 	if (auth_failover)
    581 		radius_client_auth_failover(radius);
    582 
    583 	if (acct_failover)
    584 		radius_client_acct_failover(radius);
    585 
    586 	entry = radius->msgs;
    587 	first = 0;
    588 
    589 	prev = NULL;
    590 	while (entry) {
    591 		prev_num_msgs = radius->num_msgs;
    592 		if (now.sec >= entry->next_try &&
    593 		    radius_client_retransmit(radius, entry, now.sec)) {
    594 			if (prev)
    595 				prev->next = entry->next;
    596 			else
    597 				radius->msgs = entry->next;
    598 
    599 			tmp = entry;
    600 			entry = entry->next;
    601 			radius_client_msg_free(tmp);
    602 			radius->num_msgs--;
    603 			continue;
    604 		}
    605 
    606 		if (prev_num_msgs != radius->num_msgs) {
    607 			wpa_printf(MSG_DEBUG,
    608 				   "RADIUS: Message removed from queue - restart from beginning");
    609 			entry = radius->msgs;
    610 			prev = NULL;
    611 			continue;
    612 		}
    613 
    614 		if (first == 0 || entry->next_try < first)
    615 			first = entry->next_try;
    616 
    617 		prev = entry;
    618 		entry = entry->next;
    619 	}
    620 
    621 	if (radius->msgs) {
    622 		if (first < now.sec)
    623 			first = now.sec;
    624 		eloop_cancel_timeout(radius_client_timer, radius, NULL);
    625 		eloop_register_timeout(first - now.sec, 0,
    626 				       radius_client_timer, radius, NULL);
    627 		hostapd_logger(radius->ctx, NULL, HOSTAPD_MODULE_RADIUS,
    628 			       HOSTAPD_LEVEL_DEBUG, "Next RADIUS client "
    629 			       "retransmit in %ld seconds",
    630 			       (long int) (first - now.sec));
    631 	}
    632 }
    633 
    634 
    635 static void radius_client_auth_failover(struct radius_client_data *radius)
    636 {
    637 	struct hostapd_radius_servers *conf = radius->conf;
    638 	struct hostapd_radius_server *next, *old;
    639 	struct radius_msg_list *entry;
    640 	char abuf[50];
    641 
    642 	old = conf->auth_server;
    643 	hostapd_logger(radius->ctx, NULL, HOSTAPD_MODULE_RADIUS,
    644 		       HOSTAPD_LEVEL_NOTICE,
    645 		       "No response from Authentication server %s:%d - failover",
    646 		       hostapd_ip_txt(&old->addr, abuf, sizeof(abuf)),
    647 		       old->port);
    648 
    649 	for (entry = radius->msgs; entry; entry = entry->next) {
    650 		if (entry->msg_type == RADIUS_AUTH)
    651 			old->timeouts++;
    652 	}
    653 
    654 	next = old + 1;
    655 	if (next > &(conf->auth_servers[conf->num_auth_servers - 1]))
    656 		next = conf->auth_servers;
    657 	conf->auth_server = next;
    658 	radius_change_server(radius, next, old, 1);
    659 }
    660 
    661 
    662 static void radius_client_acct_failover(struct radius_client_data *radius)
    663 {
    664 	struct hostapd_radius_servers *conf = radius->conf;
    665 	struct hostapd_radius_server *next, *old;
    666 	struct radius_msg_list *entry;
    667 	char abuf[50];
    668 
    669 	old = conf->acct_server;
    670 	hostapd_logger(radius->ctx, NULL, HOSTAPD_MODULE_RADIUS,
    671 		       HOSTAPD_LEVEL_NOTICE,
    672 		       "No response from Accounting server %s:%d - failover",
    673 		       hostapd_ip_txt(&old->addr, abuf, sizeof(abuf)),
    674 		       old->port);
    675 
    676 	for (entry = radius->msgs; entry; entry = entry->next) {
    677 		if (entry->msg_type == RADIUS_ACCT ||
    678 		    entry->msg_type == RADIUS_ACCT_INTERIM)
    679 			old->timeouts++;
    680 	}
    681 
    682 	next = old + 1;
    683 	if (next > &conf->acct_servers[conf->num_acct_servers - 1])
    684 		next = conf->acct_servers;
    685 	conf->acct_server = next;
    686 	radius_change_server(radius, next, old, 0);
    687 }
    688 
    689 
    690 static void radius_client_update_timeout(struct radius_client_data *radius)
    691 {
    692 	struct os_reltime now;
    693 	os_time_t first;
    694 	struct radius_msg_list *entry;
    695 
    696 	eloop_cancel_timeout(radius_client_timer, radius, NULL);
    697 
    698 	if (radius->msgs == NULL) {
    699 		return;
    700 	}
    701 
    702 	first = 0;
    703 	for (entry = radius->msgs; entry; entry = entry->next) {
    704 		if (first == 0 || entry->next_try < first)
    705 			first = entry->next_try;
    706 	}
    707 
    708 	os_get_reltime(&now);
    709 	if (first < now.sec)
    710 		first = now.sec;
    711 	eloop_register_timeout(first - now.sec, 0, radius_client_timer, radius,
    712 			       NULL);
    713 	hostapd_logger(radius->ctx, NULL, HOSTAPD_MODULE_RADIUS,
    714 		       HOSTAPD_LEVEL_DEBUG, "Next RADIUS client retransmit in"
    715 		       " %ld seconds", (long int) (first - now.sec));
    716 }
    717 
    718 
    719 static void radius_client_list_add(struct radius_client_data *radius,
    720 				   struct radius_msg *msg,
    721 				   RadiusType msg_type,
    722 				   const u8 *shared_secret,
    723 				   size_t shared_secret_len, const u8 *addr)
    724 {
    725 	struct radius_msg_list *entry, *prev;
    726 
    727 	if (eloop_terminated()) {
    728 		/* No point in adding entries to retransmit queue since event
    729 		 * loop has already been terminated. */
    730 		radius_msg_free(msg);
    731 		return;
    732 	}
    733 
    734 	entry = os_zalloc(sizeof(*entry));
    735 	if (entry == NULL) {
    736 		wpa_printf(MSG_INFO, "RADIUS: Failed to add packet into retransmit list");
    737 		radius_msg_free(msg);
    738 		return;
    739 	}
    740 
    741 	if (addr)
    742 		os_memcpy(entry->addr, addr, ETH_ALEN);
    743 	entry->msg = msg;
    744 	entry->msg_type = msg_type;
    745 	entry->shared_secret = shared_secret;
    746 	entry->shared_secret_len = shared_secret_len;
    747 	os_get_reltime(&entry->last_attempt);
    748 	entry->first_try = entry->last_attempt.sec;
    749 	entry->next_try = entry->first_try + RADIUS_CLIENT_FIRST_WAIT;
    750 	entry->attempts = 1;
    751 	entry->accu_attempts = 1;
    752 	entry->next_wait = RADIUS_CLIENT_FIRST_WAIT * 2;
    753 	if (entry->next_wait > RADIUS_CLIENT_MAX_WAIT)
    754 		entry->next_wait = RADIUS_CLIENT_MAX_WAIT;
    755 	entry->next = radius->msgs;
    756 	radius->msgs = entry;
    757 	radius_client_update_timeout(radius);
    758 
    759 	if (radius->num_msgs >= RADIUS_CLIENT_MAX_ENTRIES) {
    760 		wpa_printf(MSG_INFO, "RADIUS: Removing the oldest un-ACKed packet due to retransmit list limits");
    761 		prev = NULL;
    762 		while (entry->next) {
    763 			prev = entry;
    764 			entry = entry->next;
    765 		}
    766 		if (prev) {
    767 			prev->next = NULL;
    768 			radius_client_msg_free(entry);
    769 		}
    770 	} else
    771 		radius->num_msgs++;
    772 }
    773 
    774 
    775 static int radius_client_disable_pmtu_discovery(int s)
    776 {
    777 	int r = -1;
    778 #if defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DONT)
    779 	/* Turn off Path MTU discovery on IPv4/UDP sockets. */
    780 	int action = IP_PMTUDISC_DONT;
    781 	r = setsockopt(s, IPPROTO_IP, IP_MTU_DISCOVER, &action,
    782 		       sizeof(action));
    783 	if (r == -1)
    784 		wpa_printf(MSG_ERROR, "RADIUS: Failed to set IP_MTU_DISCOVER: %s",
    785 			   strerror(errno));
    786 #endif
    787 	return r;
    788 }
    789 
    790 
    791 static void radius_close_auth_socket(struct radius_client_data *radius)
    792 {
    793 	if (radius->auth_sock >= 0) {
    794 #ifdef CONFIG_RADIUS_TLS
    795 		if (radius->conf->auth_server->tls)
    796 			eloop_unregister_sock(radius->auth_sock,
    797 					      EVENT_TYPE_WRITE);
    798 #endif /* CONFIG_RADIUS_TLS */
    799 		eloop_unregister_read_sock(radius->auth_sock);
    800 		close(radius->auth_sock);
    801 		radius->auth_sock = -1;
    802 	}
    803 }
    804 
    805 
    806 static void radius_close_acct_socket(struct radius_client_data *radius)
    807 {
    808 	if (radius->acct_sock >= 0) {
    809 #ifdef CONFIG_RADIUS_TLS
    810 		if (radius->conf->acct_server->tls)
    811 			eloop_unregister_sock(radius->acct_sock,
    812 					      EVENT_TYPE_WRITE);
    813 #endif /* CONFIG_RADIUS_TLS */
    814 		eloop_unregister_read_sock(radius->acct_sock);
    815 		close(radius->acct_sock);
    816 		radius->acct_sock = -1;
    817 	}
    818 }
    819 
    820 
    821 /**
    822  * radius_client_send - Send a RADIUS request
    823  * @radius: RADIUS client context from radius_client_init()
    824  * @msg: RADIUS message to be sent
    825  * @msg_type: Message type (RADIUS_AUTH, RADIUS_ACCT, RADIUS_ACCT_INTERIM)
    826  * @addr: MAC address of the device related to this message or %NULL
    827  * Returns: 0 on success, -1 on failure
    828  *
    829  * This function is used to transmit a RADIUS authentication (RADIUS_AUTH) or
    830  * accounting request (RADIUS_ACCT or RADIUS_ACCT_INTERIM). The only difference
    831  * between accounting and interim accounting messages is that the interim
    832  * message will not be retransmitted. Instead, a callback is used to indicate
    833  * that the transmission failed for the specific station @addr so that a new
    834  * interim accounting update message can be generated with up-to-date session
    835  * data instead of trying to resend old information.
    836  *
    837  * The message is added on the retransmission queue and will be retransmitted
    838  * automatically until a response is received or maximum number of retries
    839  * (RADIUS_CLIENT_MAX_FAILOVER * RADIUS_CLIENT_NUM_FAILOVER) is reached. No
    840  * such retries are used with RADIUS_ACCT_INTERIM, i.e., such a pending message
    841  * is removed from the queue automatically on transmission failure.
    842  *
    843  * The related device MAC address can be used to identify pending messages that
    844  * can be removed with radius_client_flush_auth().
    845  */
    846 int radius_client_send(struct radius_client_data *radius,
    847 		       struct radius_msg *msg, RadiusType msg_type,
    848 		       const u8 *addr)
    849 {
    850 	struct hostapd_radius_servers *conf = radius->conf;
    851 	const u8 *shared_secret;
    852 	size_t shared_secret_len;
    853 	char *name;
    854 	int s, res;
    855 	struct wpabuf *buf;
    856 #ifdef CONFIG_RADIUS_TLS
    857 	struct wpabuf *out = NULL;
    858 	struct tls_connection *conn = NULL;
    859 	bool acct = false;
    860 #endif /* CONFIG_RADIUS_TLS */
    861 
    862 	if (msg_type == RADIUS_ACCT || msg_type == RADIUS_ACCT_INTERIM) {
    863 #ifdef CONFIG_RADIUS_TLS
    864 		acct = true;
    865 		if (radius->acct_tls)
    866 			conn = radius->acct_tls_conn;
    867 #endif /* CONFIG_RADIUS_TLS */
    868 		if (conf->acct_server && radius->acct_sock < 0)
    869 			radius_client_init_acct(radius);
    870 
    871 		if (conf->acct_server == NULL || radius->acct_sock < 0 ||
    872 		    conf->acct_server->shared_secret == NULL) {
    873 			hostapd_logger(radius->ctx, NULL,
    874 				       HOSTAPD_MODULE_RADIUS,
    875 				       HOSTAPD_LEVEL_INFO,
    876 				       "No accounting server configured");
    877 			return -1;
    878 		}
    879 		shared_secret = conf->acct_server->shared_secret;
    880 		shared_secret_len = conf->acct_server->shared_secret_len;
    881 		radius_msg_finish_acct(msg, shared_secret, shared_secret_len);
    882 		name = "accounting";
    883 		s = radius->acct_sock;
    884 		conf->acct_server->requests++;
    885 	} else {
    886 #ifdef CONFIG_RADIUS_TLS
    887 		if (radius->auth_tls)
    888 			conn = radius->auth_tls_conn;
    889 #endif /* CONFIG_RADIUS_TLS */
    890 		if (conf->auth_server && radius->auth_sock < 0)
    891 			radius_client_init_auth(radius);
    892 
    893 		if (conf->auth_server == NULL || radius->auth_sock < 0 ||
    894 		    conf->auth_server->shared_secret == NULL) {
    895 			hostapd_logger(radius->ctx, NULL,
    896 				       HOSTAPD_MODULE_RADIUS,
    897 				       HOSTAPD_LEVEL_INFO,
    898 				       "No authentication server configured");
    899 			return -1;
    900 		}
    901 		shared_secret = conf->auth_server->shared_secret;
    902 		shared_secret_len = conf->auth_server->shared_secret_len;
    903 		radius_msg_finish(msg, shared_secret, shared_secret_len);
    904 		name = "authentication";
    905 		s = radius->auth_sock;
    906 		conf->auth_server->requests++;
    907 	}
    908 
    909 	hostapd_logger(radius->ctx, NULL, HOSTAPD_MODULE_RADIUS,
    910 		       HOSTAPD_LEVEL_DEBUG, "Sending RADIUS message to %s "
    911 		       "server", name);
    912 	if (conf->msg_dumps)
    913 		radius_msg_dump(msg);
    914 
    915 #ifdef CONFIG_RADIUS_TLS
    916 	if ((acct && radius->acct_tls && !radius->acct_tls_ready) ||
    917 	    (!acct && radius->auth_tls && !radius->auth_tls_ready)) {
    918 		wpa_printf(MSG_DEBUG,
    919 			   "RADIUS: TLS connection not yet ready for TX");
    920 		goto skip_send;
    921 	}
    922 #endif /* CONFIG_RADIUS_TLS */
    923 
    924 	buf = radius_msg_get_buf(msg);
    925 #ifdef CONFIG_RADIUS_TLS
    926 	if (conn) {
    927 		out = tls_connection_encrypt(radius->tls_ctx, conn, buf);
    928 		if (!out) {
    929 			wpa_printf(MSG_INFO,
    930 				   "RADIUS: Failed to encrypt RADIUS message (TLS)");
    931 			return -1;
    932 		}
    933 		wpa_printf(MSG_DEBUG,
    934 			   "RADIUS: TLS encryption of %zu bytes of plaintext to %zu bytes of ciphertext",
    935 			   wpabuf_len(buf), wpabuf_len(out));
    936 		buf = out;
    937 	}
    938 #endif /* CONFIG_RADIUS_TLS */
    939 	wpa_printf(MSG_DEBUG, "RADIUS: Send %zu bytes to the server",
    940 		   wpabuf_len(buf));
    941 	res = send(s, wpabuf_head(buf), wpabuf_len(buf), 0);
    942 #ifdef CONFIG_RADIUS_TLS
    943 	wpabuf_free(out);
    944 #endif /* CONFIG_RADIUS_TLS */
    945 	if (res < 0)
    946 		radius_client_handle_send_error(radius, s, msg_type);
    947 
    948 #ifdef CONFIG_RADIUS_TLS
    949 skip_send:
    950 #endif /* CONFIG_RADIUS_TLS */
    951 	radius_client_list_add(radius, msg, msg_type, shared_secret,
    952 			       shared_secret_len, addr);
    953 
    954 	return 0;
    955 }
    956 
    957 
    958 #ifdef CONFIG_RADIUS_TLS
    959 
    960 static void radius_client_close_tcp(struct radius_client_data *radius,
    961 				    int sock, RadiusType msg_type)
    962 {
    963 	wpa_printf(MSG_DEBUG, "RADIUS: Closing TCP connection (sock %d)",
    964 		   sock);
    965 	if (msg_type == RADIUS_ACCT) {
    966 		radius->acct_tls_ready = false;
    967 		radius_close_acct_socket(radius);
    968 	} else {
    969 		radius->auth_tls_ready = false;
    970 		radius_close_auth_socket(radius);
    971 	}
    972 }
    973 
    974 
    975 static void
    976 radius_client_process_tls_handshake(struct radius_client_data *radius,
    977 				    int sock, RadiusType msg_type,
    978 				    u8 *buf, size_t len)
    979 {
    980 	struct wpabuf *in, *out = NULL, *appl;
    981 	struct tls_connection *conn;
    982 	int res;
    983 	bool ready = false;
    984 
    985 	wpa_printf(MSG_DEBUG,
    986 		   "RADIUS: Process %zu bytes of received TLS handshake message",
    987 		   len);
    988 
    989 	if (msg_type == RADIUS_ACCT)
    990 		conn = radius->acct_tls_conn;
    991 	else
    992 		conn = radius->auth_tls_conn;
    993 
    994 	in = wpabuf_alloc_copy(buf, len);
    995 	if (!in)
    996 		return;
    997 
    998 	appl = NULL;
    999 	out = tls_connection_handshake(radius->tls_ctx, conn, in, &appl);
   1000 	wpabuf_free(in);
   1001 	if (!out) {
   1002 		wpa_printf(MSG_DEBUG,
   1003 			   "RADIUS: Could not generate TLS handshake data");
   1004 		goto fail;
   1005 	}
   1006 
   1007 	if (tls_connection_get_failed(radius->tls_ctx, conn)) {
   1008 		wpa_printf(MSG_INFO, "RADIUS: TLS handshake failed");
   1009 		goto fail;
   1010 	}
   1011 
   1012 	if (tls_connection_established(radius->tls_ctx, conn)) {
   1013 		wpa_printf(MSG_DEBUG,
   1014 			   "RADIUS: TLS connection established (sock=%d)",
   1015 			   sock);
   1016 		if (msg_type == RADIUS_ACCT)
   1017 			radius->acct_tls_ready = true;
   1018 		else
   1019 			radius->auth_tls_ready = true;
   1020 		ready = true;
   1021 	}
   1022 
   1023 	wpa_printf(MSG_DEBUG, "RADIUS: Sending %zu bytes of TLS handshake",
   1024 		   wpabuf_len(out));
   1025 	res = send(sock, wpabuf_head(out), wpabuf_len(out), 0);
   1026 	if (res < 0) {
   1027 		wpa_printf(MSG_INFO, "RADIUS: send: %s", strerror(errno));
   1028 		goto fail;
   1029 	}
   1030 	if ((size_t) res != wpabuf_len(out)) {
   1031 		wpa_printf(MSG_INFO,
   1032 			   "RADIUS: Could not send all data for TLS handshake: only %d bytes sent",
   1033 			   res);
   1034 		goto fail;
   1035 	}
   1036 	wpabuf_free(out);
   1037 
   1038 	if (ready) {
   1039 		struct radius_msg_list *entry, *prev, *tmp;
   1040 		struct os_reltime now;
   1041 
   1042 		/* Send all pending message of matching type since the TLS
   1043 		 * tunnel has now been established. */
   1044 
   1045 		os_get_reltime(&now);
   1046 
   1047 		entry = radius->msgs;
   1048 		prev = NULL;
   1049 		while (entry) {
   1050 			if (entry->msg_type != msg_type) {
   1051 				prev = entry;
   1052 				entry = entry->next;
   1053 				continue;
   1054 			}
   1055 
   1056 			if (radius_client_retransmit(radius, entry, now.sec)) {
   1057 				if (prev)
   1058 					prev->next = entry->next;
   1059 				else
   1060 					radius->msgs = entry->next;
   1061 
   1062 				tmp = entry;
   1063 				entry = entry->next;
   1064 				radius_client_msg_free(tmp);
   1065 				radius->num_msgs--;
   1066 				continue;
   1067 			}
   1068 
   1069 			prev = entry;
   1070 			entry = entry->next;
   1071 		}
   1072 	}
   1073 
   1074 	return;
   1075 
   1076 fail:
   1077 	wpabuf_free(out);
   1078 	tls_connection_deinit(radius->tls_ctx, conn);
   1079 	if (msg_type == RADIUS_ACCT)
   1080 		radius->acct_tls_conn = NULL;
   1081 	else
   1082 		radius->auth_tls_conn = NULL;
   1083 	radius_client_close_tcp(radius, sock, msg_type);
   1084 }
   1085 
   1086 #endif /* CONFIG_RADIUS_TLS */
   1087 
   1088 
   1089 static void radius_client_receive(int sock, void *eloop_ctx, void *sock_ctx)
   1090 {
   1091 	struct radius_client_data *radius = eloop_ctx;
   1092 	struct hostapd_radius_servers *conf = radius->conf;
   1093 	RadiusType msg_type = (RadiusType)(uintptr_t) sock_ctx;
   1094 	int len, roundtrip;
   1095 	unsigned char buf[RADIUS_MAX_MSG_LEN];
   1096 	struct msghdr msghdr = {0};
   1097 	struct iovec iov;
   1098 	struct radius_msg *msg;
   1099 	struct radius_hdr *hdr;
   1100 	struct radius_rx_handler *handlers;
   1101 	size_t num_handlers, i;
   1102 	struct radius_msg_list *req, *prev_req;
   1103 	struct os_reltime now;
   1104 	struct hostapd_radius_server *rconf;
   1105 	int invalid_authenticator = 0;
   1106 #ifdef CONFIG_RADIUS_TLS
   1107 	struct tls_connection *conn = NULL;
   1108 	bool tls, tls_ready;
   1109 #endif /* CONFIG_RADIUS_TLS */
   1110 
   1111 	if (msg_type == RADIUS_ACCT) {
   1112 #ifdef CONFIG_RADIUS_TLS
   1113 		if (radius->acct_tls)
   1114 			conn = radius->acct_tls_conn;
   1115 		tls = radius->acct_tls;
   1116 		tls_ready = radius->acct_tls_ready;
   1117 #endif /* CONFIG_RADIUS_TLS */
   1118 		handlers = radius->acct_handlers;
   1119 		num_handlers = radius->num_acct_handlers;
   1120 		rconf = conf->acct_server;
   1121 	} else {
   1122 #ifdef CONFIG_RADIUS_TLS
   1123 		if (radius->auth_tls)
   1124 			conn = radius->auth_tls_conn;
   1125 		tls = radius->auth_tls;
   1126 		tls_ready = radius->auth_tls_ready;
   1127 #endif /* CONFIG_RADIUS_TLS */
   1128 		handlers = radius->auth_handlers;
   1129 		num_handlers = radius->num_auth_handlers;
   1130 		rconf = conf->auth_server;
   1131 	}
   1132 
   1133 	iov.iov_base = buf;
   1134 	iov.iov_len = RADIUS_MAX_MSG_LEN;
   1135 	msghdr.msg_iov = &iov;
   1136 	msghdr.msg_iovlen = 1;
   1137 	msghdr.msg_flags = 0;
   1138 	len = recvmsg(sock, &msghdr, MSG_DONTWAIT);
   1139 	if (len < 0) {
   1140 		wpa_printf(MSG_INFO, "recvmsg[RADIUS]: %s", strerror(errno));
   1141 		return;
   1142 	}
   1143 #ifdef CONFIG_RADIUS_TLS
   1144 	if (tls && len == 0) {
   1145 		wpa_printf(MSG_DEBUG, "RADIUS: No TCP data available");
   1146 		goto close_tcp;
   1147 	}
   1148 
   1149 	if (tls && !tls_ready) {
   1150 		radius_client_process_tls_handshake(radius, sock, msg_type,
   1151 						    buf, len);
   1152 		return;
   1153 	}
   1154 
   1155 	if (conn) {
   1156 		struct wpabuf *out, *in;
   1157 
   1158 		in = wpabuf_alloc_copy(buf, len);
   1159 		if (!in)
   1160 			return;
   1161 		wpa_printf(MSG_DEBUG,
   1162 			   "RADIUS: Process %d bytes of encrypted TLS data",
   1163 			   len);
   1164 		out = tls_connection_decrypt(radius->tls_ctx, conn, in);
   1165 		wpabuf_free(in);
   1166 		if (!out) {
   1167 			wpa_printf(MSG_INFO,
   1168 				   "RADIUS: Failed to decrypt TLS data");
   1169 			goto close_tcp;
   1170 		}
   1171 		if (wpabuf_len(out) == 0) {
   1172 			wpa_printf(MSG_DEBUG,
   1173 				   "RADIUS: Full message not yet received - continue waiting for additional TLS data");
   1174 			wpabuf_free(out);
   1175 			return;
   1176 		}
   1177 		if (wpabuf_len(out) > RADIUS_MAX_MSG_LEN) {
   1178 			wpa_printf(MSG_INFO,
   1179 				   "RADIUS: Too long RADIUS message from TLS: %zu",
   1180 				   wpabuf_len(out));
   1181 			wpabuf_free(out);
   1182 			goto close_tcp;
   1183 		}
   1184 		os_memcpy(buf, wpabuf_head(out), wpabuf_len(out));
   1185 		len = wpabuf_len(out);
   1186 		wpabuf_free(out);
   1187 	}
   1188 #endif /* CONFIG_RADIUS_TLS */
   1189 
   1190 	hostapd_logger(radius->ctx, NULL, HOSTAPD_MODULE_RADIUS,
   1191 		       HOSTAPD_LEVEL_DEBUG, "Received %d bytes from RADIUS "
   1192 		       "server", len);
   1193 
   1194 	if (msghdr.msg_flags & MSG_TRUNC) {
   1195 		wpa_printf(MSG_INFO, "RADIUS: Possibly too long UDP frame for our buffer - dropping it");
   1196 		return;
   1197 	}
   1198 
   1199 	msg = radius_msg_parse(buf, len);
   1200 	if (msg == NULL) {
   1201 		wpa_printf(MSG_INFO, "RADIUS: Parsing incoming frame failed");
   1202 		rconf->malformed_responses++;
   1203 		return;
   1204 	}
   1205 	hdr = radius_msg_get_hdr(msg);
   1206 
   1207 	hostapd_logger(radius->ctx, NULL, HOSTAPD_MODULE_RADIUS,
   1208 		       HOSTAPD_LEVEL_DEBUG, "Received RADIUS message");
   1209 	if (conf->msg_dumps)
   1210 		radius_msg_dump(msg);
   1211 
   1212 	switch (hdr->code) {
   1213 	case RADIUS_CODE_ACCESS_ACCEPT:
   1214 		rconf->access_accepts++;
   1215 		break;
   1216 	case RADIUS_CODE_ACCESS_REJECT:
   1217 		rconf->access_rejects++;
   1218 		break;
   1219 	case RADIUS_CODE_ACCESS_CHALLENGE:
   1220 		rconf->access_challenges++;
   1221 		break;
   1222 	case RADIUS_CODE_ACCOUNTING_RESPONSE:
   1223 		rconf->responses++;
   1224 		break;
   1225 	}
   1226 
   1227 	prev_req = NULL;
   1228 	req = radius->msgs;
   1229 	while (req) {
   1230 		/* TODO: also match by src addr:port of the packet when using
   1231 		 * alternative RADIUS servers (?) */
   1232 		if ((req->msg_type == msg_type ||
   1233 		     (req->msg_type == RADIUS_ACCT_INTERIM &&
   1234 		      msg_type == RADIUS_ACCT)) &&
   1235 		    radius_msg_get_hdr(req->msg)->identifier ==
   1236 		    hdr->identifier)
   1237 			break;
   1238 
   1239 		prev_req = req;
   1240 		req = req->next;
   1241 	}
   1242 
   1243 	if (req == NULL) {
   1244 		hostapd_logger(radius->ctx, NULL, HOSTAPD_MODULE_RADIUS,
   1245 			       HOSTAPD_LEVEL_DEBUG,
   1246 			       "No matching RADIUS request found (type=%d "
   1247 			       "id=%d) - dropping packet",
   1248 			       msg_type, hdr->identifier);
   1249 		goto fail;
   1250 	}
   1251 
   1252 	os_get_reltime(&now);
   1253 	roundtrip = (now.sec - req->last_attempt.sec) * 100 +
   1254 		(now.usec - req->last_attempt.usec) / 10000;
   1255 	hostapd_logger(radius->ctx, req->addr, HOSTAPD_MODULE_RADIUS,
   1256 		       HOSTAPD_LEVEL_DEBUG,
   1257 		       "Received RADIUS packet matched with a pending "
   1258 		       "request, round trip time %d.%02d sec",
   1259 		       roundtrip / 100, roundtrip % 100);
   1260 	rconf->round_trip_time = roundtrip;
   1261 
   1262 	/* Remove ACKed RADIUS packet from retransmit list */
   1263 	if (prev_req)
   1264 		prev_req->next = req->next;
   1265 	else
   1266 		radius->msgs = req->next;
   1267 	radius->num_msgs--;
   1268 
   1269 	for (i = 0; i < num_handlers; i++) {
   1270 		RadiusRxResult res;
   1271 		res = handlers[i].handler(msg, req->msg, req->shared_secret,
   1272 					  req->shared_secret_len,
   1273 					  handlers[i].data);
   1274 		switch (res) {
   1275 		case RADIUS_RX_PROCESSED:
   1276 			radius_msg_free(msg);
   1277 			/* fall through */
   1278 		case RADIUS_RX_QUEUED:
   1279 			radius_client_msg_free(req);
   1280 			return;
   1281 		case RADIUS_RX_INVALID_AUTHENTICATOR:
   1282 			invalid_authenticator++;
   1283 			/* fall through */
   1284 		case RADIUS_RX_UNKNOWN:
   1285 			/* continue with next handler */
   1286 			break;
   1287 		}
   1288 	}
   1289 
   1290 	if (invalid_authenticator)
   1291 		rconf->bad_authenticators++;
   1292 	else
   1293 		rconf->unknown_types++;
   1294 	hostapd_logger(radius->ctx, req->addr, HOSTAPD_MODULE_RADIUS,
   1295 		       HOSTAPD_LEVEL_DEBUG, "No RADIUS RX handler found "
   1296 		       "(type=%d code=%d id=%d)%s - dropping packet",
   1297 		       msg_type, hdr->code, hdr->identifier,
   1298 		       invalid_authenticator ? " [INVALID AUTHENTICATOR]" :
   1299 		       "");
   1300 	radius_client_msg_free(req);
   1301 
   1302  fail:
   1303 	radius_msg_free(msg);
   1304 	return;
   1305 
   1306 #ifdef CONFIG_RADIUS_TLS
   1307 close_tcp:
   1308 	radius_client_close_tcp(radius, sock, msg_type);
   1309 #endif /* CONFIG_RADIUS_TLS */
   1310 }
   1311 
   1312 
   1313 #ifdef CONFIG_RADIUS_TLS
   1314 static void radius_client_write_ready(int sock, void *eloop_ctx, void *sock_ctx)
   1315 {
   1316 	struct radius_client_data *radius = eloop_ctx;
   1317 	RadiusType msg_type = (uintptr_t) sock_ctx;
   1318 	struct tls_connection *conn = NULL;
   1319 	struct wpabuf *in, *out = NULL, *appl;
   1320 	int res = -1;
   1321 	struct tls_connection_params params;
   1322 	struct hostapd_radius_server *server;
   1323 
   1324 	wpa_printf(MSG_DEBUG, "RADIUS: TCP connection established - start TLS handshake (sock=%d)",
   1325 		   sock);
   1326 
   1327 	if (msg_type == RADIUS_ACCT) {
   1328 		eloop_unregister_sock(sock, EVENT_TYPE_WRITE);
   1329 		eloop_register_read_sock(sock, radius_client_receive, radius,
   1330 					 (void *) RADIUS_ACCT);
   1331 		if (radius->acct_tls_conn) {
   1332 			wpa_printf(MSG_DEBUG,
   1333 				   "RADIUS: Deinit previously used TLS connection");
   1334 			tls_connection_deinit(radius->tls_ctx,
   1335 					      radius->acct_tls_conn);
   1336 			radius->acct_tls_conn = NULL;
   1337 		}
   1338 		server = radius->conf->acct_server;
   1339 	} else {
   1340 		eloop_unregister_sock(sock, EVENT_TYPE_WRITE);
   1341 		eloop_register_read_sock(sock, radius_client_receive, radius,
   1342 					 (void *) RADIUS_AUTH);
   1343 		if (radius->auth_tls_conn) {
   1344 			wpa_printf(MSG_DEBUG,
   1345 				   "RADIUS: Deinit previously used TLS connection");
   1346 			tls_connection_deinit(radius->tls_ctx,
   1347 					      radius->auth_tls_conn);
   1348 			radius->auth_tls_conn = NULL;
   1349 		}
   1350 		server = radius->conf->auth_server;
   1351 	}
   1352 
   1353 	if (!server)
   1354 		goto fail;
   1355 
   1356 	conn = tls_connection_init(radius->tls_ctx);
   1357 	if (!conn) {
   1358 		wpa_printf(MSG_INFO,
   1359 			   "RADIUS: Failed to initiate TLS connection");
   1360 		goto fail;
   1361 	}
   1362 
   1363 	os_memset(&params, 0, sizeof(params));
   1364 	params.ca_cert = server->ca_cert;
   1365 	params.client_cert = server->client_cert;
   1366 	params.private_key = server->private_key;
   1367 	params.private_key_passwd = server->private_key_passwd;
   1368 	params.flags = TLS_CONN_DISABLE_TLSv1_0 | TLS_CONN_DISABLE_TLSv1_1;
   1369 	if (tls_connection_set_params(radius->tls_ctx, conn, &params)) {
   1370 		wpa_printf(MSG_INFO,
   1371 			   "RADIUS: Failed to set TLS connection parameters");
   1372 		goto fail;
   1373 	}
   1374 
   1375 	in = NULL;
   1376 	appl = NULL;
   1377 	out = tls_connection_handshake(radius->tls_ctx, conn, in, &appl);
   1378 	if (!out) {
   1379 		wpa_printf(MSG_DEBUG,
   1380 			   "RADIUS: Could not generate TLS handshake data");
   1381 		goto fail;
   1382 	}
   1383 
   1384 	if (tls_connection_get_failed(radius->tls_ctx, conn)) {
   1385 		wpa_printf(MSG_INFO, "RADIUS: TLS handshake failed");
   1386 		goto fail;
   1387 	}
   1388 
   1389 	wpa_printf(MSG_DEBUG, "RADIUS: Sending %zu bytes of TLS handshake",
   1390 		   wpabuf_len(out));
   1391 	res = send(sock, wpabuf_head(out), wpabuf_len(out), 0);
   1392 	if (res < 0) {
   1393 		wpa_printf(MSG_INFO, "RADIUS: send: %s", strerror(errno));
   1394 		goto fail;
   1395 	}
   1396 	if ((size_t) res != wpabuf_len(out)) {
   1397 		wpa_printf(MSG_INFO,
   1398 			   "RADIUS: Could not send all data for TLS handshake: only %d bytes sent",
   1399 			   res);
   1400 		goto fail;
   1401 	}
   1402 	wpabuf_free(out);
   1403 
   1404 	if (msg_type == RADIUS_ACCT)
   1405 		radius->acct_tls_conn = conn;
   1406 	else
   1407 		radius->auth_tls_conn = conn;
   1408 	return;
   1409 
   1410 fail:
   1411 	wpa_printf(MSG_INFO, "RADIUS: Failed to perform TLS handshake");
   1412 	tls_connection_deinit(radius->tls_ctx, conn);
   1413 	wpabuf_free(out);
   1414 	radius_client_close_tcp(radius, sock, msg_type);
   1415 }
   1416 #endif /* CONFIG_RADIUS_TLS */
   1417 
   1418 
   1419 /**
   1420  * radius_client_get_id - Get an identifier for a new RADIUS message
   1421  * @radius: RADIUS client context from radius_client_init()
   1422  * Returns: Allocated identifier
   1423  *
   1424  * This function is used to fetch a unique (among pending requests) identifier
   1425  * for a new RADIUS message.
   1426  */
   1427 u8 radius_client_get_id(struct radius_client_data *radius)
   1428 {
   1429 	struct radius_msg_list *entry, *prev, *_remove;
   1430 	u8 id = radius->next_radius_identifier++;
   1431 
   1432 	/* remove entries with matching id from retransmit list to avoid
   1433 	 * using new reply from the RADIUS server with an old request */
   1434 	entry = radius->msgs;
   1435 	prev = NULL;
   1436 	while (entry) {
   1437 		if (radius_msg_get_hdr(entry->msg)->identifier == id) {
   1438 			hostapd_logger(radius->ctx, entry->addr,
   1439 				       HOSTAPD_MODULE_RADIUS,
   1440 				       HOSTAPD_LEVEL_DEBUG,
   1441 				       "Removing pending RADIUS message, "
   1442 				       "since its id (%d) is reused", id);
   1443 			if (prev)
   1444 				prev->next = entry->next;
   1445 			else
   1446 				radius->msgs = entry->next;
   1447 			_remove = entry;
   1448 		} else {
   1449 			_remove = NULL;
   1450 			prev = entry;
   1451 		}
   1452 		entry = entry->next;
   1453 
   1454 		if (_remove)
   1455 			radius_client_msg_free(_remove);
   1456 	}
   1457 
   1458 	return id;
   1459 }
   1460 
   1461 
   1462 /**
   1463  * radius_client_flush - Flush all pending RADIUS client messages
   1464  * @radius: RADIUS client context from radius_client_init()
   1465  * @only_auth: Whether only authentication messages are removed
   1466  */
   1467 void radius_client_flush(struct radius_client_data *radius, int only_auth)
   1468 {
   1469 	struct radius_msg_list *entry, *prev, *tmp;
   1470 
   1471 	if (!radius)
   1472 		return;
   1473 
   1474 	prev = NULL;
   1475 	entry = radius->msgs;
   1476 
   1477 	while (entry) {
   1478 		if (!only_auth || entry->msg_type == RADIUS_AUTH) {
   1479 			if (prev)
   1480 				prev->next = entry->next;
   1481 			else
   1482 				radius->msgs = entry->next;
   1483 
   1484 			tmp = entry;
   1485 			entry = entry->next;
   1486 			radius_client_msg_free(tmp);
   1487 			radius->num_msgs--;
   1488 		} else {
   1489 			prev = entry;
   1490 			entry = entry->next;
   1491 		}
   1492 	}
   1493 
   1494 	if (radius->msgs == NULL)
   1495 		eloop_cancel_timeout(radius_client_timer, radius, NULL);
   1496 }
   1497 
   1498 
   1499 static void radius_client_update_acct_msgs(struct radius_client_data *radius,
   1500 					   const u8 *shared_secret,
   1501 					   size_t shared_secret_len)
   1502 {
   1503 	struct radius_msg_list *entry;
   1504 
   1505 	if (!radius)
   1506 		return;
   1507 
   1508 	for (entry = radius->msgs; entry; entry = entry->next) {
   1509 		if (entry->msg_type == RADIUS_ACCT) {
   1510 			entry->shared_secret = shared_secret;
   1511 			entry->shared_secret_len = shared_secret_len;
   1512 			radius_msg_finish_acct(entry->msg, shared_secret,
   1513 					       shared_secret_len);
   1514 		}
   1515 	}
   1516 }
   1517 
   1518 
   1519 static int
   1520 radius_change_server(struct radius_client_data *radius,
   1521 		     struct hostapd_radius_server *nserv,
   1522 		     struct hostapd_radius_server *oserv,
   1523 		     int auth)
   1524 {
   1525 	struct sockaddr_in serv, claddr;
   1526 #ifdef CONFIG_IPV6
   1527 	struct sockaddr_in6 serv6, claddr6;
   1528 #endif /* CONFIG_IPV6 */
   1529 	struct sockaddr *addr, *cl_addr;
   1530 	socklen_t addrlen, claddrlen;
   1531 	char abuf[50];
   1532 	int sel_sock;
   1533 	struct radius_msg_list *entry;
   1534 	struct hostapd_radius_servers *conf = radius->conf;
   1535 	int type = SOCK_DGRAM;
   1536 	bool tls = nserv->tls;
   1537 
   1538 	if (tls) {
   1539 #ifdef CONFIG_RADIUS_TLS
   1540 		type = SOCK_STREAM;
   1541 #else /* CONFIG_RADIUS_TLS */
   1542 		wpa_printf(MSG_ERROR, "RADIUS: TLS not supported");
   1543 		return -1;
   1544 #endif /* CONFIG_RADIUS_TLS */
   1545 	}
   1546 
   1547 	hostapd_logger(radius->ctx, NULL, HOSTAPD_MODULE_RADIUS,
   1548 		       HOSTAPD_LEVEL_INFO,
   1549 		       "%s server %s:%d",
   1550 		       auth ? "Authentication" : "Accounting",
   1551 		       hostapd_ip_txt(&nserv->addr, abuf, sizeof(abuf)),
   1552 		       nserv->port);
   1553 
   1554 	if (oserv && oserv == nserv) {
   1555 		/* Reconnect to same server, flush */
   1556 		if (auth)
   1557 			radius_client_flush(radius, 1);
   1558 	}
   1559 
   1560 	if (oserv && oserv != nserv &&
   1561 	    (nserv->shared_secret_len != oserv->shared_secret_len ||
   1562 	     os_memcmp(nserv->shared_secret, oserv->shared_secret,
   1563 		       nserv->shared_secret_len) != 0)) {
   1564 		/* Pending RADIUS packets used different shared secret, so
   1565 		 * they need to be modified. Update accounting message
   1566 		 * authenticators here. Authentication messages are removed
   1567 		 * since they would require more changes and the new RADIUS
   1568 		 * server may not be prepared to receive them anyway due to
   1569 		 * missing state information. Client will likely retry
   1570 		 * authentication, so this should not be an issue. */
   1571 		if (auth)
   1572 			radius_client_flush(radius, 1);
   1573 		else {
   1574 			radius_client_update_acct_msgs(
   1575 				radius, nserv->shared_secret,
   1576 				nserv->shared_secret_len);
   1577 		}
   1578 	}
   1579 
   1580 	/* Reset retry counters */
   1581 	for (entry = radius->msgs; oserv && entry; entry = entry->next) {
   1582 		if ((auth && entry->msg_type != RADIUS_AUTH) ||
   1583 		    (!auth && entry->msg_type != RADIUS_ACCT))
   1584 			continue;
   1585 		entry->next_try = entry->first_try + RADIUS_CLIENT_FIRST_WAIT;
   1586 		entry->attempts = 0;
   1587 		entry->next_wait = RADIUS_CLIENT_FIRST_WAIT * 2;
   1588 	}
   1589 
   1590 	if (radius->msgs) {
   1591 		eloop_cancel_timeout(radius_client_timer, radius, NULL);
   1592 		eloop_register_timeout(RADIUS_CLIENT_FIRST_WAIT, 0,
   1593 				       radius_client_timer, radius, NULL);
   1594 	}
   1595 
   1596 	switch (nserv->addr.af) {
   1597 	case AF_INET:
   1598 		os_memset(&serv, 0, sizeof(serv));
   1599 		serv.sin_family = AF_INET;
   1600 		serv.sin_addr.s_addr = nserv->addr.u.v4.s_addr;
   1601 		serv.sin_port = htons(nserv->port);
   1602 		addr = (struct sockaddr *) &serv;
   1603 		addrlen = sizeof(serv);
   1604 		sel_sock = socket(PF_INET, type, 0);
   1605 		if (sel_sock >= 0)
   1606 			radius_client_disable_pmtu_discovery(sel_sock);
   1607 		break;
   1608 #ifdef CONFIG_IPV6
   1609 	case AF_INET6:
   1610 		os_memset(&serv6, 0, sizeof(serv6));
   1611 		serv6.sin6_family = AF_INET6;
   1612 		os_memcpy(&serv6.sin6_addr, &nserv->addr.u.v6,
   1613 			  sizeof(struct in6_addr));
   1614 		serv6.sin6_port = htons(nserv->port);
   1615 		addr = (struct sockaddr *) &serv6;
   1616 		addrlen = sizeof(serv6);
   1617 		sel_sock = socket(PF_INET6, type, 0);
   1618 		break;
   1619 #endif /* CONFIG_IPV6 */
   1620 	default:
   1621 		return -1;
   1622 	}
   1623 
   1624 	if (sel_sock < 0) {
   1625 		wpa_printf(MSG_INFO,
   1626 			   "RADIUS: Failed to open server socket (af=%d auth=%d)",
   1627 			   nserv->addr.af, auth);
   1628 		return -1;
   1629 	}
   1630 
   1631 #ifdef CONFIG_RADIUS_TLS
   1632 	if (tls && fcntl(sel_sock, F_SETFL, O_NONBLOCK) != 0) {
   1633 		wpa_printf(MSG_DEBUG, "RADIUS: fnctl(O_NONBLOCK) failed: %s",
   1634 			   strerror(errno));
   1635 		close(sel_sock);
   1636 		return -1;
   1637 	}
   1638 #endif /* CONFIG_RADIUS_TLS */
   1639 
   1640 #ifdef __linux__
   1641 	if (conf->force_client_dev && conf->force_client_dev[0]) {
   1642 		if (setsockopt(sel_sock, SOL_SOCKET, SO_BINDTODEVICE,
   1643 			       conf->force_client_dev,
   1644 			       os_strlen(conf->force_client_dev)) < 0) {
   1645 			wpa_printf(MSG_ERROR,
   1646 				   "RADIUS: setsockopt[SO_BINDTODEVICE]: %s",
   1647 				   strerror(errno));
   1648 			/* Probably not a critical error; continue on and hope
   1649 			 * for the best. */
   1650 		} else {
   1651 			wpa_printf(MSG_DEBUG,
   1652 				   "RADIUS: Bound client socket to device: %s",
   1653 				   conf->force_client_dev);
   1654 		}
   1655 	}
   1656 #endif /* __linux__ */
   1657 
   1658 	if (conf->force_client_addr) {
   1659 		switch (conf->client_addr.af) {
   1660 		case AF_INET:
   1661 			os_memset(&claddr, 0, sizeof(claddr));
   1662 			claddr.sin_family = AF_INET;
   1663 			claddr.sin_addr.s_addr = conf->client_addr.u.v4.s_addr;
   1664 			claddr.sin_port = htons(0);
   1665 			cl_addr = (struct sockaddr *) &claddr;
   1666 			claddrlen = sizeof(claddr);
   1667 			break;
   1668 #ifdef CONFIG_IPV6
   1669 		case AF_INET6:
   1670 			os_memset(&claddr6, 0, sizeof(claddr6));
   1671 			claddr6.sin6_family = AF_INET6;
   1672 			os_memcpy(&claddr6.sin6_addr, &conf->client_addr.u.v6,
   1673 				  sizeof(struct in6_addr));
   1674 			claddr6.sin6_port = htons(0);
   1675 			cl_addr = (struct sockaddr *) &claddr6;
   1676 			claddrlen = sizeof(claddr6);
   1677 			break;
   1678 #endif /* CONFIG_IPV6 */
   1679 		default:
   1680 			close(sel_sock);
   1681 			return -1;
   1682 		}
   1683 
   1684 		if (bind(sel_sock, cl_addr, claddrlen) < 0) {
   1685 			wpa_printf(MSG_INFO, "bind[radius]: %s",
   1686 				   strerror(errno));
   1687 			close(sel_sock);
   1688 			return -2;
   1689 		}
   1690 	}
   1691 
   1692 	if (connect(sel_sock, addr, addrlen) < 0) {
   1693 		if (nserv->tls && errno == EINPROGRESS) {
   1694 			wpa_printf(MSG_DEBUG,
   1695 				   "RADIUS: TCP connection establishment in progress (sock %d)",
   1696 				   sel_sock);
   1697 		} else {
   1698 			wpa_printf(MSG_INFO, "connect[radius]: %s",
   1699 				   strerror(errno));
   1700 			close(sel_sock);
   1701 			return -2;
   1702 		}
   1703 	}
   1704 
   1705 #ifndef CONFIG_NATIVE_WINDOWS
   1706 	switch (nserv->addr.af) {
   1707 	case AF_INET:
   1708 		claddrlen = sizeof(claddr);
   1709 		if (getsockname(sel_sock, (struct sockaddr *) &claddr,
   1710 				&claddrlen) == 0) {
   1711 			wpa_printf(MSG_DEBUG, "RADIUS local address: %s:%u",
   1712 				   inet_ntoa(claddr.sin_addr),
   1713 				   ntohs(claddr.sin_port));
   1714 		}
   1715 		break;
   1716 #ifdef CONFIG_IPV6
   1717 	case AF_INET6: {
   1718 		claddrlen = sizeof(claddr6);
   1719 		if (getsockname(sel_sock, (struct sockaddr *) &claddr6,
   1720 				&claddrlen) == 0) {
   1721 			wpa_printf(MSG_DEBUG, "RADIUS local address: %s:%u",
   1722 				   inet_ntop(AF_INET6, &claddr6.sin6_addr,
   1723 					     abuf, sizeof(abuf)),
   1724 				   ntohs(claddr6.sin6_port));
   1725 		}
   1726 		break;
   1727 	}
   1728 #endif /* CONFIG_IPV6 */
   1729 	}
   1730 #endif /* CONFIG_NATIVE_WINDOWS */
   1731 
   1732 	if (auth) {
   1733 		radius_close_auth_socket(radius);
   1734 		radius->auth_sock = sel_sock;
   1735 	} else {
   1736 		radius_close_acct_socket(radius);
   1737 		radius->acct_sock = sel_sock;
   1738 	}
   1739 
   1740 	if (!tls)
   1741 		eloop_register_read_sock(sel_sock, radius_client_receive,
   1742 					 radius,
   1743 					 auth ? (void *) RADIUS_AUTH :
   1744 					 (void *) RADIUS_ACCT);
   1745 #ifdef CONFIG_RADIUS_TLS
   1746 	if (tls)
   1747 		eloop_register_sock(sel_sock, EVENT_TYPE_WRITE,
   1748 				    radius_client_write_ready, radius,
   1749 				    auth ? (void *) RADIUS_AUTH :
   1750 				    (void *) RADIUS_ACCT);
   1751 #endif /* CONFIG_RADIUS_TLS */
   1752 
   1753 	if (auth) {
   1754 		radius->auth_tls = nserv->tls;
   1755 		radius->auth_tls_ready = false;
   1756 	} else {
   1757 		radius->acct_tls = nserv->tls;
   1758 		radius->acct_tls_ready = false;
   1759 	}
   1760 
   1761 	return 0;
   1762 }
   1763 
   1764 
   1765 static void radius_retry_primary_timer(void *eloop_ctx, void *timeout_ctx)
   1766 {
   1767 	struct radius_client_data *radius = eloop_ctx;
   1768 	struct hostapd_radius_servers *conf = radius->conf;
   1769 	struct hostapd_radius_server *oserv;
   1770 
   1771 	if (radius->auth_sock >= 0 && conf->auth_servers &&
   1772 	    conf->auth_server != conf->auth_servers) {
   1773 		oserv = conf->auth_server;
   1774 		conf->auth_server = conf->auth_servers;
   1775 		if (radius_change_server(radius, conf->auth_server, oserv,
   1776 					 1) < 0) {
   1777 			conf->auth_server = oserv;
   1778 			radius_change_server(radius, oserv, conf->auth_server,
   1779 					     1);
   1780 		}
   1781 	}
   1782 
   1783 	if (radius->acct_sock >= 0 && conf->acct_servers &&
   1784 	    conf->acct_server != conf->acct_servers) {
   1785 		oserv = conf->acct_server;
   1786 		conf->acct_server = conf->acct_servers;
   1787 		if (radius_change_server(radius, conf->acct_server, oserv,
   1788 					 0) < 0) {
   1789 			conf->acct_server = oserv;
   1790 			radius_change_server(radius, oserv, conf->acct_server,
   1791 					     0);
   1792 		}
   1793 	}
   1794 
   1795 	if (conf->retry_primary_interval)
   1796 		eloop_register_timeout(conf->retry_primary_interval, 0,
   1797 				       radius_retry_primary_timer, radius,
   1798 				       NULL);
   1799 }
   1800 
   1801 
   1802 static int radius_client_init_auth(struct radius_client_data *radius)
   1803 {
   1804 	radius_close_auth_socket(radius);
   1805 	return radius_change_server(radius, radius->conf->auth_server, NULL, 1);
   1806 }
   1807 
   1808 
   1809 static int radius_client_init_acct(struct radius_client_data *radius)
   1810 {
   1811 	radius_close_acct_socket(radius);
   1812 	return radius_change_server(radius, radius->conf->acct_server, NULL, 0);
   1813 }
   1814 
   1815 
   1816 #ifdef CONFIG_RADIUS_TLS
   1817 static void radius_tls_event_cb(void *ctx, enum tls_event ev,
   1818 				union tls_event_data *data)
   1819 {
   1820 	wpa_printf(MSG_DEBUG, "RADIUS: TLS event %d", ev);
   1821 }
   1822 #endif /* CONFIG_RADIUS_TLS */
   1823 
   1824 
   1825 /**
   1826  * radius_client_init - Initialize RADIUS client
   1827  * @ctx: Callback context to be used in hostapd_logger() calls
   1828  * @conf: RADIUS client configuration (RADIUS servers)
   1829  * Returns: Pointer to private RADIUS client context or %NULL on failure
   1830  *
   1831  * The caller is responsible for keeping the configuration data available for
   1832  * the lifetime of the RADIUS client, i.e., until radius_client_deinit() is
   1833  * called for the returned context pointer.
   1834  */
   1835 struct radius_client_data *
   1836 radius_client_init(void *ctx, struct hostapd_radius_servers *conf)
   1837 {
   1838 	struct radius_client_data *radius;
   1839 
   1840 	radius = os_zalloc(sizeof(struct radius_client_data));
   1841 	if (radius == NULL)
   1842 		return NULL;
   1843 
   1844 	radius->ctx = ctx;
   1845 	radius->conf = conf;
   1846 	radius->auth_sock = radius->acct_sock = -1;
   1847 
   1848 	if (conf->auth_server && radius_client_init_auth(radius) == -1) {
   1849 		radius_client_deinit(radius);
   1850 		return NULL;
   1851 	}
   1852 
   1853 	if (conf->acct_server && radius_client_init_acct(radius) == -1) {
   1854 		radius_client_deinit(radius);
   1855 		return NULL;
   1856 	}
   1857 
   1858 	if (conf->retry_primary_interval)
   1859 		eloop_register_timeout(conf->retry_primary_interval, 0,
   1860 				       radius_retry_primary_timer, radius,
   1861 				       NULL);
   1862 
   1863 #ifdef CONFIG_RADIUS_TLS
   1864 	if ((conf->auth_server && conf->auth_server->tls) ||
   1865 	    (conf->acct_server && conf->acct_server->tls)) {
   1866 		struct tls_config tls_conf;
   1867 
   1868 		os_memset(&tls_conf, 0, sizeof(tls_conf));
   1869 		tls_conf.event_cb = radius_tls_event_cb;
   1870 		radius->tls_ctx = tls_init(&tls_conf);
   1871 		if (!radius->tls_ctx) {
   1872 			radius_client_deinit(radius);
   1873 			return NULL;
   1874 		}
   1875 	}
   1876 #endif /* CONFIG_RADIUS_TLS */
   1877 
   1878 
   1879 	return radius;
   1880 }
   1881 
   1882 
   1883 /**
   1884  * radius_client_deinit - Deinitialize RADIUS client
   1885  * @radius: RADIUS client context from radius_client_init()
   1886  */
   1887 void radius_client_deinit(struct radius_client_data *radius)
   1888 {
   1889 	if (!radius)
   1890 		return;
   1891 
   1892 	radius_close_auth_socket(radius);
   1893 	radius_close_acct_socket(radius);
   1894 
   1895 	eloop_cancel_timeout(radius_retry_primary_timer, radius, NULL);
   1896 
   1897 	radius_client_flush(radius, 0);
   1898 	os_free(radius->auth_handlers);
   1899 	os_free(radius->acct_handlers);
   1900 #ifdef CONFIG_RADIUS_TLS
   1901 	if (radius->tls_ctx) {
   1902 		tls_connection_deinit(radius->tls_ctx, radius->auth_tls_conn);
   1903 		tls_connection_deinit(radius->tls_ctx, radius->acct_tls_conn);
   1904 		tls_deinit(radius->tls_ctx);
   1905 	}
   1906 #endif /* CONFIG_RADIUS_TLS */
   1907 	os_free(radius);
   1908 }
   1909 
   1910 
   1911 /**
   1912  * radius_client_flush_auth - Flush pending RADIUS messages for an address
   1913  * @radius: RADIUS client context from radius_client_init()
   1914  * @addr: MAC address of the related device
   1915  *
   1916  * This function can be used to remove pending RADIUS authentication messages
   1917  * that are related to a specific device. The addr parameter is matched with
   1918  * the one used in radius_client_send() call that was used to transmit the
   1919  * authentication request.
   1920  */
   1921 void radius_client_flush_auth(struct radius_client_data *radius,
   1922 			      const u8 *addr)
   1923 {
   1924 	struct radius_msg_list *entry, *prev, *tmp;
   1925 
   1926 	prev = NULL;
   1927 	entry = radius->msgs;
   1928 	while (entry) {
   1929 		if (entry->msg_type == RADIUS_AUTH &&
   1930 		    ether_addr_equal(entry->addr, addr)) {
   1931 			hostapd_logger(radius->ctx, addr,
   1932 				       HOSTAPD_MODULE_RADIUS,
   1933 				       HOSTAPD_LEVEL_DEBUG,
   1934 				       "Removing pending RADIUS authentication"
   1935 				       " message for removed client");
   1936 
   1937 			if (prev)
   1938 				prev->next = entry->next;
   1939 			else
   1940 				radius->msgs = entry->next;
   1941 
   1942 			tmp = entry;
   1943 			entry = entry->next;
   1944 			radius_client_msg_free(tmp);
   1945 			radius->num_msgs--;
   1946 			continue;
   1947 		}
   1948 
   1949 		prev = entry;
   1950 		entry = entry->next;
   1951 	}
   1952 }
   1953 
   1954 
   1955 static int radius_client_dump_auth_server(char *buf, size_t buflen,
   1956 					  struct hostapd_radius_server *serv,
   1957 					  struct radius_client_data *cli)
   1958 {
   1959 	int pending = 0;
   1960 	struct radius_msg_list *msg;
   1961 	char abuf[50];
   1962 
   1963 	if (cli) {
   1964 		for (msg = cli->msgs; msg; msg = msg->next) {
   1965 			if (msg->msg_type == RADIUS_AUTH)
   1966 				pending++;
   1967 		}
   1968 	}
   1969 
   1970 	return os_snprintf(buf, buflen,
   1971 			   "radiusAuthServerIndex=%d\n"
   1972 			   "radiusAuthServerAddress=%s\n"
   1973 			   "radiusAuthClientServerPortNumber=%d\n"
   1974 			   "radiusAuthClientRoundTripTime=%d\n"
   1975 			   "radiusAuthClientAccessRequests=%u\n"
   1976 			   "radiusAuthClientAccessRetransmissions=%u\n"
   1977 			   "radiusAuthClientAccessAccepts=%u\n"
   1978 			   "radiusAuthClientAccessRejects=%u\n"
   1979 			   "radiusAuthClientAccessChallenges=%u\n"
   1980 			   "radiusAuthClientMalformedAccessResponses=%u\n"
   1981 			   "radiusAuthClientBadAuthenticators=%u\n"
   1982 			   "radiusAuthClientPendingRequests=%u\n"
   1983 			   "radiusAuthClientTimeouts=%u\n"
   1984 			   "radiusAuthClientUnknownTypes=%u\n"
   1985 			   "radiusAuthClientPacketsDropped=%u\n",
   1986 			   serv->index,
   1987 			   hostapd_ip_txt(&serv->addr, abuf, sizeof(abuf)),
   1988 			   serv->port,
   1989 			   serv->round_trip_time,
   1990 			   serv->requests,
   1991 			   serv->retransmissions,
   1992 			   serv->access_accepts,
   1993 			   serv->access_rejects,
   1994 			   serv->access_challenges,
   1995 			   serv->malformed_responses,
   1996 			   serv->bad_authenticators,
   1997 			   pending,
   1998 			   serv->timeouts,
   1999 			   serv->unknown_types,
   2000 			   serv->packets_dropped);
   2001 }
   2002 
   2003 
   2004 static int radius_client_dump_acct_server(char *buf, size_t buflen,
   2005 					  struct hostapd_radius_server *serv,
   2006 					  struct radius_client_data *cli)
   2007 {
   2008 	int pending = 0;
   2009 	struct radius_msg_list *msg;
   2010 	char abuf[50];
   2011 
   2012 	if (cli) {
   2013 		for (msg = cli->msgs; msg; msg = msg->next) {
   2014 			if (msg->msg_type == RADIUS_ACCT ||
   2015 			    msg->msg_type == RADIUS_ACCT_INTERIM)
   2016 				pending++;
   2017 		}
   2018 	}
   2019 
   2020 	return os_snprintf(buf, buflen,
   2021 			   "radiusAccServerIndex=%d\n"
   2022 			   "radiusAccServerAddress=%s\n"
   2023 			   "radiusAccClientServerPortNumber=%d\n"
   2024 			   "radiusAccClientRoundTripTime=%d\n"
   2025 			   "radiusAccClientRequests=%u\n"
   2026 			   "radiusAccClientRetransmissions=%u\n"
   2027 			   "radiusAccClientResponses=%u\n"
   2028 			   "radiusAccClientMalformedResponses=%u\n"
   2029 			   "radiusAccClientBadAuthenticators=%u\n"
   2030 			   "radiusAccClientPendingRequests=%u\n"
   2031 			   "radiusAccClientTimeouts=%u\n"
   2032 			   "radiusAccClientUnknownTypes=%u\n"
   2033 			   "radiusAccClientPacketsDropped=%u\n",
   2034 			   serv->index,
   2035 			   hostapd_ip_txt(&serv->addr, abuf, sizeof(abuf)),
   2036 			   serv->port,
   2037 			   serv->round_trip_time,
   2038 			   serv->requests,
   2039 			   serv->retransmissions,
   2040 			   serv->responses,
   2041 			   serv->malformed_responses,
   2042 			   serv->bad_authenticators,
   2043 			   pending,
   2044 			   serv->timeouts,
   2045 			   serv->unknown_types,
   2046 			   serv->packets_dropped);
   2047 }
   2048 
   2049 
   2050 /**
   2051  * radius_client_get_mib - Get RADIUS client MIB information
   2052  * @radius: RADIUS client context from radius_client_init()
   2053  * @buf: Buffer for returning MIB data in text format
   2054  * @buflen: Maximum buf length in octets
   2055  * Returns: Number of octets written into the buffer
   2056  */
   2057 int radius_client_get_mib(struct radius_client_data *radius, char *buf,
   2058 			  size_t buflen)
   2059 {
   2060 	struct hostapd_radius_servers *conf;
   2061 	int i;
   2062 	struct hostapd_radius_server *serv;
   2063 	int count = 0;
   2064 
   2065 	if (!radius)
   2066 		return 0;
   2067 
   2068 	conf = radius->conf;
   2069 
   2070 	if (conf->auth_servers) {
   2071 		for (i = 0; i < conf->num_auth_servers; i++) {
   2072 			serv = &conf->auth_servers[i];
   2073 			count += radius_client_dump_auth_server(
   2074 				buf + count, buflen - count, serv,
   2075 				serv == conf->auth_server ?
   2076 				radius : NULL);
   2077 		}
   2078 	}
   2079 
   2080 	if (conf->acct_servers) {
   2081 		for (i = 0; i < conf->num_acct_servers; i++) {
   2082 			serv = &conf->acct_servers[i];
   2083 			count += radius_client_dump_acct_server(
   2084 				buf + count, buflen - count, serv,
   2085 				serv == conf->acct_server ?
   2086 				radius : NULL);
   2087 		}
   2088 	}
   2089 
   2090 	return count;
   2091 }
   2092 
   2093 
   2094 void radius_client_reconfig(struct radius_client_data *radius,
   2095 			    struct hostapd_radius_servers *conf)
   2096 {
   2097 	if (radius)
   2098 		radius->conf = conf;
   2099 }
   2100