From 666fed838b4a2d5bd086aebe3e424a7616d14af4 Mon Sep 17 00:00:00 2001 From: "Alan T. DeKok" Date: Fri, 9 Aug 2024 19:22:38 -0400 Subject: [PATCH] use pctx for packet ctx --- src/lib/bio/packet.h | 12 +++++------ src/protocols/radius/all.mk | 4 +++- src/protocols/radius/client.c | 35 +++++++++++++++++++------------ src/protocols/radius/client_tcp.c | 4 ++-- src/protocols/radius/client_udp.c | 4 ++-- 5 files changed, 35 insertions(+), 24 deletions(-) diff --git a/src/lib/bio/packet.h b/src/lib/bio/packet.h index 7dc90ec82b..fd7b605cdd 100644 --- a/src/lib/bio/packet.h +++ b/src/lib/bio/packet.h @@ -105,7 +105,7 @@ struct fr_bio_packet_s { * it again later. * * @param my the packet-based bio - * @param[out] request_ctx_p the larger context for the original request packet + * @param[out] pctx_p the larger context for the original request packet * @param[out] packet_p Where the allocated #fr_packet_t will be stored * @param[out] out_ctx for the output pairs * @param[out] out decoded output pairs @@ -113,9 +113,9 @@ struct fr_bio_packet_s { * - <0 on error. This is fr_bio_error(FOO) * - 0 for success */ -static inline CC_HINT(nonnull) int fr_bio_packet_read(fr_bio_packet_t *my, void **request_ctx_p, fr_packet_t **packet_p, TALLOC_CTX *out_ctx, fr_pair_list_t *out) +static inline CC_HINT(nonnull) int fr_bio_packet_read(fr_bio_packet_t *my, void **pctx_p, fr_packet_t **packet_p, TALLOC_CTX *out_ctx, fr_pair_list_t *out) { - return my->read(my, request_ctx_p, packet_p, out_ctx, out); + return my->read(my, pctx_p, packet_p, out_ctx, out); } /** Write a packet to a packet BIO @@ -125,14 +125,14 @@ static inline CC_HINT(nonnull) int fr_bio_packet_read(fr_bio_packet_t *my, void * it again later. * * @param my the packet-based bio - * @param request_ctx the larger context for the packet + * @param pctx the larger context for the packet * @param packet the output packet descriptor. Contains raw protocol data (IDs, counts, etc.) * @param list of pairs to write * @return * - <0 on error. This is fr_bio_error(FOO) * - 0 for success */ -static inline CC_HINT(nonnull) int fr_bio_packet_write(fr_bio_packet_t *my, void *request_ctx, fr_packet_t *packet, fr_pair_list_t *list) +static inline CC_HINT(nonnull) int fr_bio_packet_write(fr_bio_packet_t *my, void *pctx, fr_packet_t *packet, fr_pair_list_t *list) { int rcode; @@ -141,7 +141,7 @@ static inline CC_HINT(nonnull) int fr_bio_packet_write(fr_bio_packet_t *my, void */ if (my->write_blocked) return fr_bio_error(IO_WOULD_BLOCK); - rcode = my->write(my, request_ctx, packet, list); + rcode = my->write(my, pctx, packet, list); if (rcode == 0) return 0; my->write_blocked = (rcode == fr_bio_error(IO_WOULD_BLOCK)); diff --git a/src/protocols/radius/all.mk b/src/protocols/radius/all.mk index 8bf2c5b547..0712f83298 100644 --- a/src/protocols/radius/all.mk +++ b/src/protocols/radius/all.mk @@ -23,7 +23,9 @@ SOURCES += \ client_udp.c \ client_tcp.c \ id.c \ - bio.c + bio.c \ + server.c \ + server_udp.c TGT_PREREQS += libfreeradius-bio$(L) endif diff --git a/src/protocols/radius/client.c b/src/protocols/radius/client.c index ecb5473e14..e48a00f447 100644 --- a/src/protocols/radius/client.c +++ b/src/protocols/radius/client.c @@ -163,7 +163,7 @@ fr_radius_client_fd_bio_t *fr_radius_client_fd_bio_alloc(TALLOC_CTX *ctx, size_t return my; } -int fr_radius_client_fd_bio_write(fr_radius_client_fd_bio_t *my, void *request_ctx, fr_packet_t *packet, fr_pair_list_t *list) +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; @@ -199,7 +199,7 @@ int fr_radius_client_fd_bio_write(fr_radius_client_fd_bio_t *my, void *request_c id_ctx = fr_radius_code_id_pop(my->codes, packet); if (!id_ctx) goto all_ids_used; } - id_ctx->request_ctx = request_ctx; + id_ctx->request_ctx = pctx; fr_assert(id_ctx->packet == packet); /* @@ -244,30 +244,39 @@ int fr_radius_client_fd_bio_write(fr_radius_client_fd_bio_t *my, void *request_c packet->data_len = end - my->buffer; fr_nbo_from_uint16(my->buffer + 2, packet->data_len); - packet->data = talloc_array(packet, uint8_t, packet->data_len); - if (!packet->data) goto fail; - slen = fr_radius_sign(my->buffer, NULL, (uint8_t const *) my->cfg.verify.secret, my->cfg.verify.secret_len); if (slen < 0) goto fail; + /* + * The other BIOs will take care of calling fr_radius_client_bio_write_blocked() when the write + * is blocked. + * + * The "next" BIO is a memory one, which can store the entire packet. So write() never returns a + * partial packet. + */ slen = fr_bio_write(my->common.bio, &packet->socket, my->buffer, packet->data_len); if (slen < 0) { + fr_assert((slen != fr_bio_error(IO_WOULD_BLOCK)) || my->common.write_blocked); + fr_radius_code_id_push(my->codes, packet); return slen; } + fr_assert((size_t) slen == packet->data_len); + /* - * Only after successful write do we copy the data back to the packet structure. + * We only allocate packet data after writing it to the socket. If the write fails, we avoid a + * memory alloc / free. */ - memcpy(packet->data, my->buffer, packet->data_len); - memcpy(packet->vector, packet->data + 4, RADIUS_AUTH_VECTOR_LENGTH); + packet->data = talloc_array(packet, uint8_t, packet->data_len); + if (!packet->data) goto fail; /* - * We are using an outgoing memory bio, which takes care of writing partial packets. As a - * result, our call to the bio will always return that a full packet was written. + * Only after successful write do we copy the data back to the packet structure. */ - fr_assert((size_t) slen == packet->data_len); + memcpy(packet->data, my->buffer, packet->data_len); + memcpy(packet->vector, packet->data + 4, RADIUS_AUTH_VECTOR_LENGTH); return 0; } @@ -542,7 +551,7 @@ int fr_radius_client_fd_bio_cancel(fr_bio_packet_t *bio, fr_packet_t *packet) return 0; } -int fr_radius_client_fd_bio_read(fr_bio_packet_t *bio, void **request_ctx_p, fr_packet_t **packet_p, +int fr_radius_client_fd_bio_read(fr_bio_packet_t *bio, void **pctx_p, fr_packet_t **packet_p, UNUSED TALLOC_CTX *out_ctx, fr_pair_list_t *out) { ssize_t slen; @@ -600,7 +609,7 @@ int fr_radius_client_fd_bio_read(fr_bio_packet_t *bio, void **request_ctx_p, fr_ return -1; } - *request_ctx_p = original->uctx; + *pctx_p = original->uctx; *packet_p = reply; return 1; diff --git a/src/protocols/radius/client_tcp.c b/src/protocols/radius/client_tcp.c index 207f686d8c..f4687166c9 100644 --- a/src/protocols/radius/client_tcp.c +++ b/src/protocols/radius/client_tcp.c @@ -31,7 +31,7 @@ RCSID("$Id$") /** Allocate an ID, and write one packet. * */ -static int fr_radius_client_tcp_bio_write(fr_bio_packet_t *bio, void *request_ctx, fr_packet_t *packet, fr_pair_list_t *list) +static int fr_radius_client_tcp_bio_write(fr_bio_packet_t *bio, void *pctx, fr_packet_t *packet, fr_pair_list_t *list) { fr_radius_client_fd_bio_t *my = talloc_get_type_abort(bio, fr_radius_client_fd_bio_t); @@ -40,7 +40,7 @@ static int fr_radius_client_tcp_bio_write(fr_bio_packet_t *bio, void *request_ct */ fr_assert(!packet->data); - return fr_radius_client_fd_bio_write(my, request_ctx, packet, list); + return fr_radius_client_fd_bio_write(my, pctx, packet, list); } /** Allocate a RADIUS bio for writing client packets diff --git a/src/protocols/radius/client_udp.c b/src/protocols/radius/client_udp.c index 4998afb1d4..df198ede4c 100644 --- a/src/protocols/radius/client_udp.c +++ b/src/protocols/radius/client_udp.c @@ -31,12 +31,12 @@ RCSID("$Id$") /** Allocate an ID, and write one packet. * */ -static int fr_radius_client_udp_bio_write(fr_bio_packet_t *bio, void *request_ctx, fr_packet_t *packet, fr_pair_list_t *list) +static int fr_radius_client_udp_bio_write(fr_bio_packet_t *bio, void *pctx, fr_packet_t *packet, fr_pair_list_t *list) { ssize_t slen; fr_radius_client_fd_bio_t *my = talloc_get_type_abort(bio, fr_radius_client_fd_bio_t); - if (!packet->data) return fr_radius_client_fd_bio_write(my, request_ctx, packet, list); + if (!packet->data) return fr_radius_client_fd_bio_write(my, pctx, packet, list); slen = fr_bio_write(my->common.bio, &packet->socket, packet->data, packet->data_len); if (slen <= 0) return -1; -- 2.47.3