From: Alan T. DeKok Date: Sun, 18 Aug 2024 21:13:56 +0000 (-0400) Subject: update for new fr_radius_encode() API X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=58cad73d21e4ae4d593fde46b0a2446489389dfa;p=thirdparty%2Ffreeradius-server.git update for new fr_radius_encode() API and call activate() from connect(), if the connection is already open. --- diff --git a/src/protocols/radius/client.c b/src/protocols/radius/client.c index e48a00f4478..55501ef3f36 100644 --- a/src/protocols/radius/client.c +++ b/src/protocols/radius/client.c @@ -146,7 +146,7 @@ fr_radius_client_fd_bio_t *fr_radius_client_fd_bio_alloc(TALLOC_CTX *ctx, size_t /* * Set up the connected status. */ - my->info.connected = (my->info.fd_info->type == FR_BIO_FD_CONNECTED) && (my->info.fd_info->state == FR_BIO_FD_STATE_OPEN); + my->info.connected = false; /* * If we're supposed to be connected (but aren't), then ensure that we don't keep trying to @@ -160,13 +160,19 @@ fr_radius_client_fd_bio_t *fr_radius_client_fd_bio_alloc(TALLOC_CTX *ctx, size_t } } + my->proto_ctx = (fr_radius_ctx_t) { + .secret = (char const *) my->cfg.verify.secret, + .secret_length = my->cfg.verify.secret_len, + .secure_transport = false, + .proxy_state = my->cfg.proxy_state, + }; + return my; } int fr_radius_client_fd_bio_write(fr_radius_client_fd_bio_t *my, void *pctx, fr_packet_t *packet, fr_pair_list_t *list) { ssize_t slen; - uint8_t *end; fr_radius_id_ctx_t *id_ctx; fr_assert(!packet->data); @@ -213,9 +219,17 @@ int fr_radius_client_fd_bio_write(fr_radius_client_fd_bio_t *my, void *pctx, fr_ /* * Encode the packet. */ - slen = fr_radius_encode(my->buffer, sizeof(my->buffer), NULL, - (char const *) my->cfg.verify.secret, my->cfg.verify.secret_len, - packet->code, packet->id, list); + slen = fr_radius_encode(&FR_DBUFF_TMP(my->buffer, sizeof(my->buffer)), list, &(fr_radius_encode_ctx_t) { + .common = &my->proto_ctx, + .request_authenticator = NULL, + .rand_ctx = (fr_fast_rand_t) { + .a = fr_rand(), + .b = fr_rand(), + }, + .code = packet->code, + .id = packet->id, + .add_proxy_state = my->cfg.add_proxy_state, + }); if (slen < 0) { fail: fr_radius_code_id_push(my->codes, packet); @@ -223,26 +237,7 @@ int fr_radius_client_fd_bio_write(fr_radius_client_fd_bio_t *my, void *pctx, fr_ } fr_assert(slen >= RADIUS_HEADER_LENGTH); - - end = my->buffer + slen; - - /* - * Add our own Proxy-State if requested. - * - * @todo - don't add Proxy-State for status checks, which could also be Access-Request or - * Accounting-Request. Note also that Status-Server packets should bypass the normal write - * routines, and instead be run by internal timers. - */ - if (my->cfg.add_proxy_state && (packet->code != FR_RADIUS_CODE_STATUS_SERVER) && ((end + 6) < (my->buffer + sizeof(my->buffer)))) { - end[0] = FR_PROXY_STATE; - end[1] = 6; - memcpy(&end[2], &my->cfg.proxy_state, sizeof(my->cfg.proxy_state)); - - end += 6; - } - - packet->data_len = end - my->buffer; - fr_nbo_from_uint16(my->buffer + 2, packet->data_len); + packet->data_len = slen; slen = fr_radius_sign(my->buffer, NULL, (uint8_t const *) my->cfg.verify.secret, my->cfg.verify.secret_len); @@ -665,7 +660,15 @@ static void fr_radius_client_bio_activate(fr_bio_t *bio) my->info.connected = true; - talloc_const_free(&my->ev); + /* + * Stop any connection timeout. + */ + if (my->ev) talloc_const_free(&my->ev); + + /* + * Tell the application that the connection has been activated. + */ + my->common.cb.activate(&my->common); } /** We failed to connect in the given timeout, the connection is dead. @@ -677,7 +680,7 @@ static void fr_radius_client_bio_connect_timer(NDEBUG_UNUSED fr_event_list_t *el fr_assert(my->info.retry_info->el == el); - talloc_const_free(&my->ev); + if (my->ev) talloc_const_free(&my->ev); if (my->common.cb.failed) my->common.cb.failed(&my->common); } @@ -686,7 +689,6 @@ static void fr_radius_client_bio_connect_timer(NDEBUG_UNUSED fr_event_list_t *el void fr_radius_client_bio_connect(NDEBUG_UNUSED fr_event_list_t *el, NDEBUG_UNUSED int fd, UNUSED int flags, void *uctx) { fr_radius_client_fd_bio_t *my = talloc_get_type_abort(uctx, fr_radius_client_fd_bio_t); - int rcode; fr_assert(my->common.cb.activate); fr_assert(my->info.retry_info->el == el); @@ -697,26 +699,24 @@ void fr_radius_client_bio_connect(NDEBUG_UNUSED fr_event_list_t *el, NDEBUG_UNUS * unconnected socket. It calls our activation routine before the application has a chance to * call our connect routine. */ - if (my->info.connected) goto activate; - - fr_assert(my->info.fd_info->type == FR_BIO_FD_CONNECTED); - fr_assert(my->info.fd_info->state == FR_BIO_FD_STATE_CONNECTING); + if (my->info.connected) return; /* - * Try to connect it. + * We don't pass the callbacks to fr_bio_fd_alloc(), so it can't call our activate routine. + * As a result, we have to check if the FD is open, and then call it ourselves. */ - rcode = fr_bio_fd_connect(my->fd); - fr_assert(rcode >= 0); + if (my->info.fd_info->state == FR_BIO_FD_STATE_OPEN) { + fr_radius_client_bio_activate(my->fd); + return; + } - my->info.connected = true; + fr_assert(my->info.fd_info->type == FR_BIO_FD_CONNECTED); + fr_assert(my->info.fd_info->state == FR_BIO_FD_STATE_CONNECTING); -activate: /* - * Stop any connection timeout. + * Try to connect it. Any magic handling is done in the callbacks. */ - talloc_const_free(&my->ev); - - my->common.cb.activate(&my->common); + (void) fr_bio_fd_connect(my->fd); } diff --git a/src/protocols/radius/client_priv.h b/src/protocols/radius/client_priv.h index fca93f3208e..19e784cbbf1 100644 --- a/src/protocols/radius/client_priv.h +++ b/src/protocols/radius/client_priv.h @@ -40,6 +40,8 @@ typedef struct { fr_socket_t reply_socket; + fr_radius_ctx_t proto_ctx; + fr_bio_t *retry; fr_bio_t *mem; fr_bio_t *fd;