From: Alan T. DeKok Date: Mon, 28 Oct 2024 23:27:52 +0000 (-0400) Subject: fr_struct_from_network() always creates nested attributes X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=fd603d7cf924b3743a6d242dc7ec52ced66f2daf;p=thirdparty%2Ffreeradius-server.git fr_struct_from_network() always creates nested attributes --- diff --git a/src/lib/util/struct.c b/src/lib/util/struct.c index b977aefecc2..a87a9510bfb 100644 --- a/src/lib/util/struct.c +++ b/src/lib/util/struct.c @@ -32,7 +32,7 @@ RCSID("$Id$") */ ssize_t fr_struct_from_network(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_attr_t const *parent, uint8_t const *data, size_t data_len, - bool nested, void *decode_ctx, + void *decode_ctx, fr_pair_decode_value_t decode_value, fr_pair_decode_value_t decode_tlv) { unsigned int child_num; @@ -55,23 +55,17 @@ ssize_t fr_struct_from_network(TALLOC_CTX *ctx, fr_pair_list_t *out, /* * Start a child list. */ - if (!nested) { - fr_pair_list_init(&child_list_head); - child_list = &child_list_head; - child_ctx = ctx; - } else { - fr_assert(parent->type == FR_TYPE_STRUCT); - - struct_vp = fr_pair_afrom_da(ctx, parent); - if (!struct_vp) { - fr_strerror_const("out of memory"); - return -1; - } + fr_assert(parent->type == FR_TYPE_STRUCT); - fr_pair_list_init(&child_list_head); /* still used elsewhere */ - child_list = &struct_vp->vp_group; - child_ctx = struct_vp; + struct_vp = fr_pair_afrom_da(ctx, parent); + if (!struct_vp) { + fr_strerror_const("out of memory"); + return -1; } + + fr_pair_list_init(&child_list_head); /* still used elsewhere */ + child_list = &struct_vp->vp_group; + child_ctx = struct_vp; child_num = 1; key_vp = NULL; @@ -315,11 +309,7 @@ ssize_t fr_struct_from_network(TALLOC_CTX *ctx, fr_pair_list_t *out, FR_PROTO_TRACE("fr_struct_from_network - failed decoding child VP %s", vp->da->name); talloc_free(vp); unknown: - if (nested) { - TALLOC_FREE(struct_vp); - } else { - fr_pair_list_free(child_list); - } + TALLOC_FREE(struct_vp); slen = fr_pair_raw_from_network(ctx, out, parent, data, data_len); if (slen < 0) return slen; @@ -389,7 +379,7 @@ ssize_t fr_struct_from_network(TALLOC_CTX *ctx, fr_pair_list_t *out, } else { fr_assert(child->type == FR_TYPE_STRUCT); - slen = fr_struct_from_network(child_ctx, child_list, child, p, end - p, nested, + slen = fr_struct_from_network(child_ctx, child_list, child, p, end - p, decode_ctx, decode_value, decode_tlv); if (slen <= 0) { FR_PROTO_TRACE("substruct %s decoding failed", child->name); @@ -402,12 +392,8 @@ ssize_t fr_struct_from_network(TALLOC_CTX *ctx, fr_pair_list_t *out, } done: - if (!nested) { - fr_pair_list_append(out, child_list); /* Wind to the end of the new pairs */ - } else { - fr_assert(struct_vp != NULL); - fr_pair_append(out, struct_vp); - } + fr_assert(struct_vp != NULL); + fr_pair_append(out, struct_vp); FR_PROTO_TRACE("used %zd bytes", data_len); return p - data; diff --git a/src/lib/util/struct.h b/src/lib/util/struct.h index ef0a351572a..6f06d4bd17f 100644 --- a/src/lib/util/struct.h +++ b/src/lib/util/struct.h @@ -36,7 +36,7 @@ extern "C" { ssize_t fr_struct_from_network(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_attr_t const *parent, uint8_t const *data, size_t data_len, - bool nested, void *decode_ctx, + void *decode_ctx, fr_pair_decode_value_t decode_value, fr_pair_decode_value_t decode_tlv) CC_HINT(nonnull(2,3,4)); ssize_t fr_struct_to_network(fr_dbuff_t *dbuff, fr_da_stack_t *da_stack, unsigned int depth, diff --git a/src/protocols/arp/base.c b/src/protocols/arp/base.c index 1ae2e631210..5deb6d5ea17 100644 --- a/src/protocols/arp/base.c +++ b/src/protocols/arp/base.c @@ -254,7 +254,7 @@ ssize_t fr_arp_decode(TALLOC_CTX *ctx, fr_pair_list_t *out, uint8_t const *packe /* * If the packet is too long, we discard any extra data. */ - return fr_struct_from_network(ctx, out, attr_arp_packet, packet, FR_ARP_PACKET_SIZE, true, + return fr_struct_from_network(ctx, out, attr_arp_packet, packet, FR_ARP_PACKET_SIZE, NULL, NULL, NULL); } diff --git a/src/protocols/bfd/decode.c b/src/protocols/bfd/decode.c index 81e33fdf9dd..debfba70d72 100644 --- a/src/protocols/bfd/decode.c +++ b/src/protocols/bfd/decode.c @@ -75,7 +75,7 @@ ssize_t fr_bfd_decode(TALLOC_CTX *ctx, fr_pair_list_t *out, bfd = (bfd_packet_t const *) packet; - slen = fr_struct_from_network(ctx, out, attr_bfd_packet, packet, bfd->length, true, + slen = fr_struct_from_network(ctx, out, attr_bfd_packet, packet, bfd->length, &packet_ctx, decode_value, NULL); if (slen < 0) return slen; diff --git a/src/protocols/dhcpv4/decode.c b/src/protocols/dhcpv4/decode.c index 120ea0b59c6..904fac7b39a 100644 --- a/src/protocols/dhcpv4/decode.c +++ b/src/protocols/dhcpv4/decode.c @@ -102,7 +102,7 @@ static ssize_t decode_value(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_attr_t * Structs create their own VP wrapper. */ if (da->type == FR_TYPE_STRUCT) { - slen = fr_struct_from_network(ctx, out, da, data, data_len, true, + slen = fr_struct_from_network(ctx, out, da, data, data_len, decode_ctx, decode_value_trampoline, decode_tlv_trampoline); if (slen < 0) return slen; diff --git a/src/protocols/dhcpv6/decode.c b/src/protocols/dhcpv6/decode.c index 229367b33a8..c33c1390574 100644 --- a/src/protocols/dhcpv6/decode.c +++ b/src/protocols/dhcpv6/decode.c @@ -176,7 +176,7 @@ static ssize_t decode_value(TALLOC_CTX *ctx, fr_pair_list_t *out, break; case FR_TYPE_STRUCT: - slen = fr_struct_from_network(ctx, out, parent, data, data_len, true, + slen = fr_struct_from_network(ctx, out, parent, data, data_len, decode_ctx, decode_value_trampoline, decode_tlv_trampoline); if (slen < 0) goto raw; diff --git a/src/protocols/dns/decode.c b/src/protocols/dns/decode.c index 414fd452997..6097a513850 100644 --- a/src/protocols/dns/decode.c +++ b/src/protocols/dns/decode.c @@ -141,7 +141,7 @@ static ssize_t decode_value(TALLOC_CTX *ctx, fr_pair_list_t *out, break; case FR_TYPE_STRUCT: - slen = fr_struct_from_network(ctx, out, parent, data, data_len, true, + slen = fr_struct_from_network(ctx, out, parent, data, data_len, decode_ctx, decode_value_trampoline, NULL); if (slen < 0) return slen; return data_len; @@ -246,7 +246,7 @@ static ssize_t decode_record(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_attr_ FR_PROTO_HEX_DUMP(p, end - p, "fr_dns_decode - %s %d/%d", attr->name, i, count); - slen = fr_struct_from_network(ctx, out, attr, p, end - p, true, + slen = fr_struct_from_network(ctx, out, attr, p, end - p, packet_ctx, decode_value_trampoline, decode_tlv_trampoline); if (slen < 0) return slen; if (!slen) break; @@ -278,7 +278,7 @@ ssize_t fr_dns_decode(TALLOC_CTX *ctx, fr_pair_list_t *out, uint8_t const *packe /* * Decode the header. */ - slen = fr_struct_from_network(ctx, out, attr_dns_packet, packet, DNS_HDR_LEN, true, + slen = fr_struct_from_network(ctx, out, attr_dns_packet, packet, DNS_HDR_LEN, packet_ctx, decode_value_trampoline, NULL); /* no TLVs in the header */ if (slen < 0) { fr_strerror_printf("Failed decoding DNS header - %s", fr_strerror()); @@ -361,7 +361,7 @@ static ssize_t decode_rr(TALLOC_CTX *ctx, fr_pair_list_t *out, UNUSED fr_dict_at return -1; } - slen = fr_struct_from_network(ctx, out, attr_dns_rr, data, data_len, true, + slen = fr_struct_from_network(ctx, out, attr_dns_rr, data, data_len, decode_ctx, decode_value_trampoline, decode_tlv_trampoline); if (slen < 0) return slen; diff --git a/src/protocols/radius/decode.c b/src/protocols/radius/decode.c index 44f690a3fc2..a10c5e60373 100644 --- a/src/protocols/radius/decode.c +++ b/src/protocols/radius/decode.c @@ -452,6 +452,8 @@ static ssize_t decode_rfc(TALLOC_CTX *ctx, fr_pair_list_t *out, da = fr_dict_attr_child_by_num(parent, attr); if (!da) { + fprintf(stderr, "RAW %d - %s %u\n", __LINE__, parent->name, attr); + da = fr_dict_attr_unknown_raw_afrom_num(packet_ctx->tmp_ctx, parent, attr); if (!da) return PAIR_DECODE_FATAL_ERROR; slen = fr_pair_raw_from_network(ctx, out, da, data + 2, len - 2); @@ -685,6 +687,7 @@ ssize_t fr_radius_decode_tlv(TALLOC_CTX *ctx, fr_pair_list_t *out, * Child is unknown and not a TLV: build an unknown attr */ if (fr_radius_decode_tlv_ok(p + 2, p[1] - 2, 1, 1) < 0) { + fprintf(stderr, "RAW %d - %s %u\n", __LINE__, parent->name, p[0]); child = fr_dict_attr_unknown_raw_afrom_num(packet_ctx->tmp_ctx, parent, p[0]); if (!child) { error: @@ -817,6 +820,7 @@ static ssize_t decode_vsa_internal(TALLOC_CTX *ctx, fr_pair_list_t *out, * well formed, so we just go create a raw VP. */ } else if ((dv->length == 0) || (fr_radius_decode_tlv_ok(data + dv->type + dv->length, attrlen - (dv->type + dv->length), dv->type, dv->length) < 0)) { + fprintf(stderr, "RAW %d - %s %u\n", __LINE__, parent->name, attribute); da = fr_dict_attr_unknown_raw_afrom_num(packet_ctx->tmp_ctx, parent, attribute); if (!da) return -1; @@ -1789,7 +1793,7 @@ ssize_t fr_radius_decode_pair_value(TALLOC_CTX *ctx, fr_pair_list_t *out, * attribute, OR it's already been grouped * into a contiguous memory buffer. */ - ret = fr_struct_from_network(ctx, out, parent, p, attr_len, true, + ret = fr_struct_from_network(ctx, out, parent, p, attr_len, packet_ctx, decode_value_trampoline, decode_tlv_trampoline); if (ret < 0) goto raw; return attr_len; diff --git a/src/protocols/tacacs/decode.c b/src/protocols/tacacs/decode.c index ab36459f3c6..65119e48ca5 100644 --- a/src/protocols/tacacs/decode.c +++ b/src/protocols/tacacs/decode.c @@ -509,7 +509,7 @@ ssize_t fr_tacacs_decode(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_attr_t co /* * Call the struct encoder to do the actual work. */ - if (fr_struct_from_network(ctx, out, attr_tacacs_packet, buffer, buffer_len, true, NULL, NULL, NULL) < 0) { + if (fr_struct_from_network(ctx, out, attr_tacacs_packet, buffer, buffer_len, NULL, NULL, NULL) < 0) { fr_strerror_printf("Failed decoding TACACS header - %s", fr_strerror()); return -1; }