]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
hoist encode_cursor() function to common API
authorAlan T. DeKok <aland@freeradius.org>
Mon, 11 Sep 2023 18:59:14 +0000 (14:59 -0400)
committerAlan T. DeKok <aland@freeradius.org>
Mon, 11 Sep 2023 19:05:03 +0000 (15:05 -0400)
src/lib/util/encode.c
src/lib/util/encode.h
src/lib/util/struct.c
src/lib/util/struct.h
src/protocols/dhcpv4/encode.c
src/protocols/dhcpv6/encode.c
src/protocols/dns/encode.c

index 5030c8534e8fcc4a2a25edc1f576578a5d01bdc2..bfda83880337464f944e44b3215d14ed54c0035c 100644 (file)
@@ -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);
+}
index 754803324cddbe77c11877eb3bfdc0bc38547157..e4f86db5d4f1accf6e444cbf43ad65f3f77cfae4 100644 (file)
@@ -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
 }
index 344f0ba831180c4397c4d89a2422d75d6ae974a6..800f5c6bde1f3008fa1ace641a0f8974e71ff849 100644 (file)
@@ -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) {
index ad6ff37fa1c2e82e51a9ddecdb55eaacba09f875..ef0a351572a7367899fa2f5d81114b9a978f8ab1 100644 (file)
@@ -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
 }
index 980d160fbc1c9e2caf616bcfe24dd8e4d68fdaae..dce93f68043fcc9dc011492ad12c586f96842b05 100644 (file)
@@ -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
index 7f8193eab44766b22f33e5b349f4430f624c633f..c31d6917ff934a881fae70803cff8ef870443664 100644 (file)
@@ -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;
 
        /*
index 9b1e23b40e5b1224790d7d82913f1d4726ebf07b..bef5418b7842f84bc18fb2f25943a303c01d6e18 100644 (file)
@@ -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++;