From: Alan T. DeKok Date: Mon, 11 Sep 2023 18:59:14 +0000 (-0400) Subject: hoist encode_cursor() function to common API X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9dbb419d61e9d8b7b51d08f228776cc2af14b923;p=thirdparty%2Ffreeradius-server.git hoist encode_cursor() function to common API --- diff --git a/src/lib/util/encode.c b/src/lib/util/encode.c index 5030c8534e8..bfda8388033 100644 --- a/src/lib/util/encode.c +++ b/src/lib/util/encode.c @@ -67,3 +67,36 @@ ssize_t fr_pair_array_to_network(fr_dbuff_t *dbuff, fr_da_stack_t *da_stack, int return fr_dbuff_set(dbuff, &work_dbuff); } + +ssize_t fr_pair_cursor_to_network(fr_dbuff_t *dbuff, + fr_da_stack_t *da_stack, unsigned int depth, + fr_dcursor_t *cursor, void *encode_ctx, fr_encode_dbuff_t encode_pair) +{ + fr_dbuff_t work_dbuff = FR_DBUFF(dbuff); + fr_pair_t const *vp; + fr_dict_attr_t const *da = da_stack->da[depth]; + ssize_t len; + + while ((vp = fr_dcursor_current(cursor)) != NULL) { + FR_PROTO_STACK_PRINT(da_stack, depth); + + len = encode_pair(&work_dbuff, da_stack, depth + 1, cursor, encode_ctx); + if (len < 0) return len; + + /* + * If nothing updated the attribute, stop + */ + if (!fr_dcursor_current(cursor) || (vp == fr_dcursor_current(cursor))) break; + + /* + * We can encode multiple children, if after + * rebuilding the DA Stack, the attribute at this + * depth is the same. + */ + if ((da != da_stack->da[depth]) || (da_stack->depth < da->depth)) break; + } + + FR_PROTO_HEX_DUMP(fr_dbuff_start(&work_dbuff), fr_dbuff_used(&work_dbuff), "Done cursor"); + + return fr_dbuff_set(dbuff, &work_dbuff); +} diff --git a/src/lib/util/encode.h b/src/lib/util/encode.h index 754803324cd..e4f86db5d4f 100644 --- a/src/lib/util/encode.h +++ b/src/lib/util/encode.h @@ -41,8 +41,10 @@ typedef ssize_t (*fr_encode_dbuff_t)(fr_dbuff_t *dbuff, fr_da_stack_t *da_stack, fr_dcursor_t *cursor, void *encode_ctx); ssize_t fr_pair_array_to_network(fr_dbuff_t *dbuff, fr_da_stack_t *da_stack, int depth, - fr_dcursor_t *cursor, void *encode_ctx, fr_encode_dbuff_t encode_value); + fr_dcursor_t *cursor, void *encode_ctx, fr_encode_dbuff_t encode_value) CC_HINT(nonnull(1,2,4,6)); +ssize_t fr_pair_cursor_to_network(fr_dbuff_t *dbuff, fr_da_stack_t *da_stack, unsigned int depth, + fr_dcursor_t *cursor, void *encode_ctx, fr_encode_dbuff_t encode_pair) CC_HINT(nonnull(1,2,4,6)); #ifdef __cplusplus } diff --git a/src/lib/util/struct.c b/src/lib/util/struct.c index 344f0ba8311..800f5c6bde1 100644 --- a/src/lib/util/struct.c +++ b/src/lib/util/struct.c @@ -478,7 +478,7 @@ static void *struct_next_encodable(fr_dlist_head_t *list, void *current, void *u ssize_t fr_struct_to_network(fr_dbuff_t *dbuff, fr_da_stack_t *da_stack, unsigned int depth, fr_dcursor_t *parent_cursor, void *encode_ctx, - fr_encode_dbuff_t encode_value, fr_encode_dbuff_t encode_cursor) + fr_encode_dbuff_t encode_value, fr_encode_dbuff_t encode_pair) { fr_dbuff_t work_dbuff; fr_dbuff_marker_t hdr; @@ -774,7 +774,7 @@ ssize_t fr_struct_to_network(fr_dbuff_t *dbuff, fr_proto_da_stack_build(da_stack, vp->da); len = fr_struct_to_network(&work_dbuff, da_stack, depth + 2, /* note + 2 !!! */ - cursor, encode_ctx, encode_value, encode_cursor); + cursor, encode_ctx, encode_value, encode_pair); if (len < 0) return len; goto done; } @@ -792,7 +792,7 @@ ssize_t fr_struct_to_network(fr_dbuff_t *dbuff, fr_proto_da_stack_build(da_stack, vp->da->parent); len = fr_struct_to_network(&work_dbuff, da_stack, depth + 2, /* note + 2 !!! */ - cursor, encode_ctx, encode_value, encode_cursor); + cursor, encode_ctx, encode_value, encode_pair); if (len < 0) return len; goto done; } @@ -817,7 +817,7 @@ done: if (tlv && vp) { ssize_t slen; - if (!encode_cursor) { + if (!encode_pair) { fr_strerror_printf("Asked to encode child attribute %s, but we were not passed an encoding function", tlv->name); return PAIR_ENCODE_FATAL_ERROR; @@ -825,18 +825,8 @@ done: fr_proto_da_stack_build(da_stack, vp->da); - /* - * Encode any TLV attributes which are part of this structure. - */ - while (vp && (da_stack->da[depth] == parent) && (da_stack->depth >= parent->depth)) { - slen = encode_cursor(&work_dbuff, da_stack, depth + 1, cursor, encode_ctx); - if (slen < 0) return slen; - - vp = fr_dcursor_current(cursor); - if (!vp) break; - - fr_proto_da_stack_build(da_stack, vp->da); - } + slen = fr_pair_cursor_to_network(&work_dbuff, da_stack, depth + 1, cursor, encode_ctx, encode_pair); + if (slen < 0) return slen; } if (do_length) { diff --git a/src/lib/util/struct.h b/src/lib/util/struct.h index ad6ff37fa1c..ef0a351572a 100644 --- a/src/lib/util/struct.h +++ b/src/lib/util/struct.h @@ -41,7 +41,7 @@ ssize_t fr_struct_from_network(TALLOC_CTX *ctx, fr_pair_list_t *out, ssize_t fr_struct_to_network(fr_dbuff_t *dbuff, fr_da_stack_t *da_stack, unsigned int depth, fr_dcursor_t *cursor, void *encode_ctx, - fr_encode_dbuff_t encode_value, fr_encode_dbuff_t encode_cursor) CC_HINT(nonnull(1,2,4)); + fr_encode_dbuff_t encode_value, fr_encode_dbuff_t encode_pair) CC_HINT(nonnull(1,2,4)); #ifdef __cplusplus } diff --git a/src/protocols/dhcpv4/encode.c b/src/protocols/dhcpv4/encode.c index 980d160fbc1..dce93f68043 100644 --- a/src/protocols/dhcpv4/encode.c +++ b/src/protocols/dhcpv4/encode.c @@ -42,10 +42,6 @@ static ssize_t encode_child(fr_dbuff_t *dbuff, fr_da_stack_t *da_stack, unsigned int depth, fr_dcursor_t *cursor, void *encode_ctx); -static ssize_t encode_cursor(fr_dbuff_t *dbuff, - fr_da_stack_t *da_stack, unsigned int depth, - fr_dcursor_t *cursor, void *encode_ctx); - /** Write DHCP option value into buffer * * Does not include DHCP option length or number. @@ -76,7 +72,7 @@ static ssize_t encode_value(fr_dbuff_t *dbuff, * Structures are special. */ if ((vp->vp_type == FR_TYPE_STRUCT) || (da->type == FR_TYPE_STRUCT)) { - slen = fr_struct_to_network(&work_dbuff, da_stack, depth, cursor, encode_ctx, encode_value, encode_cursor); + slen = fr_struct_to_network(&work_dbuff, da_stack, depth, cursor, encode_ctx, encode_value, encode_child); if (slen <= 0) return slen; /* @@ -278,42 +274,6 @@ static ssize_t extend_option(fr_dbuff_t *dbuff, fr_dbuff_marker_t *hdr, size_t l #define DHCPV4_OPT_HDR_LEN (2) -static ssize_t encode_cursor(fr_dbuff_t *dbuff, - fr_da_stack_t *da_stack, unsigned int depth, - fr_dcursor_t *cursor, void *encode_ctx) -{ - fr_dbuff_t work_dbuff = FR_DBUFF(dbuff); - fr_pair_t const *vp = fr_dcursor_current(cursor); - fr_dict_attr_t const *da = da_stack->da[depth]; - ssize_t len; - fr_dbuff_extend_status_t status = FR_DBUFF_EXTENDABLE; - - while (fr_dbuff_extend_lowat(&status, &work_dbuff, DHCPV4_OPT_HDR_LEN) > DHCPV4_OPT_HDR_LEN) { - FR_PROTO_STACK_PRINT(da_stack, depth); - - len = encode_child(&work_dbuff, da_stack, depth + 1, cursor, encode_ctx); - if (len < 0) return len; - - /* - * If nothing updated the attribute, stop - */ - if (!fr_dcursor_current(cursor) || (vp == fr_dcursor_current(cursor))) break; - - /* - * We can encode multiple sub TLVs, if after - * rebuilding the TLV Stack, the attribute - * at this depth is the same. - */ - if ((da != da_stack->da[depth]) || (da_stack->depth < da->depth)) break; - vp = fr_dcursor_current(cursor); - } - - FR_PROTO_HEX_DUMP(fr_dbuff_start(&work_dbuff), fr_dbuff_used(&work_dbuff), "Done TLV body"); - - return fr_dbuff_set(dbuff, &work_dbuff); -} - - /** Write out an RFC option header and option data * * @note May coalesce options with fixed width values diff --git a/src/protocols/dhcpv6/encode.c b/src/protocols/dhcpv6/encode.c index 7f8193eab44..c31d6917ff9 100644 --- a/src/protocols/dhcpv6/encode.c +++ b/src/protocols/dhcpv6/encode.c @@ -49,9 +49,9 @@ static ssize_t encode_tlv(fr_dbuff_t *dbuff, fr_da_stack_t *da_stack, unsigned int depth, fr_dcursor_t *cursor, void *encode_ctx); -static ssize_t encode_cursor(fr_dbuff_t *dbuff, - fr_da_stack_t *da_stack, unsigned int depth, - fr_dcursor_t *cursor, void *encode_ctx); +static ssize_t encode_child(fr_dbuff_t *dbuff, + fr_da_stack_t *da_stack, unsigned int depth, + fr_dcursor_t *cursor, void *encode_ctx); /** Macro-like function for encoding an option header * @@ -93,7 +93,7 @@ static ssize_t encode_value(fr_dbuff_t *dbuff, * Pack multiple attributes into into a single option */ if ((vp->vp_type == FR_TYPE_STRUCT) || (da->type == FR_TYPE_STRUCT)) { - slen = fr_struct_to_network(&work_dbuff, da_stack, depth, cursor, encode_ctx, encode_value, encode_cursor); + slen = fr_struct_to_network(&work_dbuff, da_stack, depth, cursor, encode_ctx, encode_value, encode_child); if (slen <= 0) return slen; /* @@ -435,41 +435,6 @@ static ssize_t encode_child(fr_dbuff_t *dbuff, return fr_dbuff_set(dbuff, &work_dbuff); } -static ssize_t encode_cursor(fr_dbuff_t *dbuff, - fr_da_stack_t *da_stack, unsigned int depth, - fr_dcursor_t *cursor, void *encode_ctx) -{ - fr_dbuff_t work_dbuff = FR_DBUFF(dbuff); - fr_pair_t const *vp = fr_dcursor_current(cursor); - fr_dict_attr_t const *da = da_stack->da[depth]; - ssize_t len; - fr_dbuff_extend_status_t status = FR_DBUFF_EXTENDABLE; - - while (fr_dbuff_extend_lowat(&status, &work_dbuff, DHCPV6_OPT_HDR_LEN) > DHCPV6_OPT_HDR_LEN) { - FR_PROTO_STACK_PRINT(da_stack, depth); - - len = encode_child(&work_dbuff, da_stack, depth + 1, cursor, encode_ctx); - if (len < 0) return len; - - /* - * If nothing updated the attribute, stop - */ - if (!fr_dcursor_current(cursor) || (vp == fr_dcursor_current(cursor))) break; - - /* - * We can encode multiple sub TLVs, if after - * rebuilding the TLV Stack, the attribute - * at this depth is the same. - */ - if ((da != da_stack->da[depth]) || (da_stack->depth < da->depth)) break; - vp = fr_dcursor_current(cursor); - } - - FR_PROTO_HEX_DUMP(fr_dbuff_start(&work_dbuff), fr_dbuff_used(&work_dbuff), "Done TLV body"); - - return fr_dbuff_set(dbuff, &work_dbuff); -} - /** Encode an RFC format TLV. * * This could be a standard attribute, or a TLV data type. @@ -541,7 +506,7 @@ static ssize_t encode_tlv(fr_dbuff_t *dbuff, FR_DBUFF_ADVANCE_RETURN(&work_dbuff, DHCPV6_OPT_HDR_LEN); /* Make room for option header */ - len = encode_cursor(&work_dbuff, da_stack, depth, cursor, encode_ctx); + len = fr_pair_cursor_to_network(&work_dbuff, da_stack, depth, cursor, encode_ctx, encode_child); if (len < 0) return len; /* diff --git a/src/protocols/dns/encode.c b/src/protocols/dns/encode.c index 9b1e23b40e5..bef5418b784 100644 --- a/src/protocols/dns/encode.c +++ b/src/protocols/dns/encode.c @@ -48,7 +48,7 @@ static ssize_t encode_tlv(fr_dbuff_t *dbuff, fr_da_stack_t *da_stack, unsigned int depth, fr_dcursor_t *cursor, void *encode_ctx); -static ssize_t encode_cursor(fr_dbuff_t *dbuff, +static ssize_t encode_child(fr_dbuff_t *dbuff, fr_da_stack_t *da_stack, unsigned int depth, fr_dcursor_t *cursor, void *encode_ctx); @@ -97,7 +97,7 @@ static ssize_t encode_value(fr_dbuff_t *dbuff, fr_pair_dcursor_init(&child_cursor, &vp->vp_group); - slen = fr_struct_to_network(&work_dbuff, da_stack, depth, &child_cursor, encode_ctx, encode_value, encode_cursor); + slen = fr_struct_to_network(&work_dbuff, da_stack, depth, &child_cursor, encode_ctx, encode_value, encode_child); if (slen < 0) return slen; /* @@ -112,7 +112,7 @@ static ssize_t encode_value(fr_dbuff_t *dbuff, * Flat-list */ if (da->type == FR_TYPE_STRUCT) { - slen = fr_struct_to_network(&work_dbuff, da_stack, depth, cursor, encode_ctx, encode_value, encode_cursor); + slen = fr_struct_to_network(&work_dbuff, da_stack, depth, cursor, encode_ctx, encode_value, encode_child); if (slen <= 0) return slen; /* @@ -276,41 +276,6 @@ static ssize_t encode_child(fr_dbuff_t *dbuff, return fr_dbuff_set(dbuff, &work_dbuff); } -static ssize_t encode_cursor(fr_dbuff_t *dbuff, - fr_da_stack_t *da_stack, unsigned int depth, - fr_dcursor_t *cursor, void *encode_ctx) -{ - fr_dbuff_t work_dbuff = FR_DBUFF(dbuff); - fr_pair_t const *vp = fr_dcursor_current(cursor); - fr_dict_attr_t const *da = da_stack->da[depth]; - ssize_t len; - fr_dbuff_extend_status_t status = FR_DBUFF_EXTENDABLE; - - while (fr_dbuff_extend_lowat(&status, &work_dbuff, DNS_OPT_HDR_LEN) > DNS_OPT_HDR_LEN) { - FR_PROTO_STACK_PRINT(da_stack, depth); - - len = encode_child(&work_dbuff, da_stack, depth + 1, cursor, encode_ctx); - if (len < 0) return len; - - /* - * If nothing updated the attribute, stop - */ - if (!fr_dcursor_current(cursor) || (vp == fr_dcursor_current(cursor))) break; - - /* - * We can encode multiple sub TLVs, if after - * rebuilding the TLV Stack, the attribute - * at this depth is the same. - */ - if ((da != da_stack->da[depth]) || (da_stack->depth < da->depth)) break; - vp = fr_dcursor_current(cursor); - } - - FR_PROTO_HEX_DUMP(fr_dbuff_start(&work_dbuff), fr_dbuff_used(&work_dbuff), "Done TLV body"); - - return fr_dbuff_set(dbuff, &work_dbuff); -} - /** Encode an RFC format TLV. * * This could be a standard attribute, or a TLV data type. @@ -382,7 +347,7 @@ static ssize_t encode_tlv(fr_dbuff_t *dbuff, FR_DBUFF_ADVANCE_RETURN(&work_dbuff, DNS_OPT_HDR_LEN); /* Make room for option header */ - len = encode_cursor(&work_dbuff, da_stack, depth, cursor, encode_ctx); + len = fr_pair_cursor_to_network(&work_dbuff, da_stack, depth, cursor, encode_ctx, encode_child); if (len < 0) return len; /* @@ -428,12 +393,12 @@ static ssize_t fr_dns_encode_rr(fr_dbuff_t *dbuff, fr_dcursor_t *cursor, void *e fr_pair_dcursor_init(&child_cursor, &vp->vp_group); - slen = fr_struct_to_network(&work_dbuff, &da_stack, 0, &child_cursor, encode_ctx, encode_value, encode_cursor); + slen = fr_struct_to_network(&work_dbuff, &da_stack, 0, &child_cursor, encode_ctx, encode_value, encode_child); if (slen <= 0) return slen; (void) fr_dcursor_next(cursor); } else { - slen = fr_struct_to_network(&work_dbuff, &da_stack, 0, cursor, encode_ctx, encode_value, encode_cursor); + slen = fr_struct_to_network(&work_dbuff, &da_stack, 0, cursor, encode_ctx, encode_value, encode_child); if (slen <= 0) return slen; } @@ -465,7 +430,7 @@ static ssize_t encode_record(fr_dbuff_t *dbuff, fr_da_stack_t *da_stack, fr_pair fr_dcursor_t child_cursor; fr_pair_dcursor_init(&child_cursor, &vp->vp_group); - slen = fr_struct_to_network(&work_dbuff, da_stack, 0, &child_cursor, packet_ctx, encode_value, encode_cursor); + slen = fr_struct_to_network(&work_dbuff, da_stack, 0, &child_cursor, packet_ctx, encode_value, encode_child); if (slen <= 0) return slen; count++;