]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
move common code to struct_to_network()
authorAlan T. DeKok <aland@freeradius.org>
Sat, 28 Nov 2020 23:09:08 +0000 (18:09 -0500)
committerAlan T. DeKok <aland@freeradius.org>
Sat, 28 Nov 2020 23:25:25 +0000 (18:25 -0500)
src/lib/util/struct.c
src/protocols/dhcpv6/encode.c
src/protocols/radius/encode.c

index 2f213f14e1a4de2557f786536afdde664907938f..7fb62c2f07ef497e91fa5bee7a4ec3aa80e159d8 100644 (file)
@@ -388,9 +388,18 @@ static int put_bits_dbuff(fr_dbuff_t *dbuff, uint8_t *p, int start_bit, uint8_t
        return start_bit % 8;
 }
 
+static int8_t pair_sort_increasing(void const *a, void const *b)
+{
+       fr_pair_t const *my_a = a;
+       fr_pair_t const *my_b = b;
+
+       return (my_a->da->attr > my_b->da->attr) - (my_a->da->attr < my_b->da->attr);
+}
+
+
 ssize_t fr_struct_to_network(fr_dbuff_t *dbuff,
                             fr_da_stack_t *da_stack, unsigned int depth,
-                            fr_cursor_t *cursor, void *encoder_ctx,
+                            fr_cursor_t *parent_cursor, void *encoder_ctx,
                             fr_encode_dbuff_t encode_value, fr_encode_dbuff_t encode_tlv)
 {
        fr_dbuff_t              work_dbuff = FR_DBUFF_NO_ADVANCE(dbuff);
@@ -399,8 +408,9 @@ ssize_t fr_struct_to_network(fr_dbuff_t *dbuff,
        unsigned int            child_num = 1;
        bool                    do_length = false;
        uint8_t                 bit_buffer = 0;
-       fr_pair_t const         *vp = fr_cursor_current(cursor);
+       fr_pair_t const         *vp = fr_cursor_current(parent_cursor);
        fr_dict_attr_t const    *key_da, *parent, *tlv = NULL;
+       fr_cursor_t             child_cursor, *cursor;
 
        if (!vp) {
                fr_strerror_printf("%s: Can't encode empty struct", __FUNCTION__);
@@ -416,6 +426,33 @@ ssize_t fr_struct_to_network(fr_dbuff_t *dbuff,
                return -1;
        }
 
+       /*
+        *      If we get passed a struct VP, sort it's children.
+        */
+       if (vp->da->type == FR_TYPE_STRUCT) {
+               fr_pair_t *sorted = fr_cursor_current(parent_cursor); /* NOT const */
+
+               fr_pair_list_sort(&sorted->vp_group, pair_sort_increasing);
+               fr_cursor_init(&child_cursor, &sorted->vp_group);
+
+               /*
+                *      Always skip the VP containing the struct.
+                *
+                *      @todo - do this only on success.
+                */
+               (void) fr_cursor_next(parent_cursor);
+
+               /*
+                *      Build the da_stack for the new structure.
+                */
+               vp = fr_cursor_current(&child_cursor);
+               fr_proto_da_stack_build(da_stack, vp ? vp->da : NULL);
+
+               cursor = &child_cursor;
+       } else {
+               cursor = parent_cursor;
+       }
+
        /*
         *      @todo - if we get a child which *eventually* has the
         *      given parent, then allow encoding of that struct, too.
index e6a8408293b7fcdc88616f39bc24fa35824ee6de..41b290a4167c36c2600eff66bed5a83d660157ff 100644 (file)
@@ -81,14 +81,6 @@ static inline ssize_t encode_option_hdr(fr_dbuff_t *dbuff, uint16_t option, size
 }
 
 
-static int8_t pair_sort_increasing(void const *a, void const *b)
-{
-       fr_pair_t const *my_a = a;
-       fr_pair_t const *my_b = b;
-
-       return (my_a->da->attr > my_b->da->attr) - (my_a->da->attr < my_b->da->attr);
-}
-
 static ssize_t encode_value(fr_dbuff_t *dbuff,
                            fr_da_stack_t *da_stack, unsigned int depth,
                            fr_cursor_t *cursor, void *encoder_ctx)
@@ -104,26 +96,10 @@ static ssize_t encode_value(fr_dbuff_t *dbuff,
        /*
         *      Pack multiple attributes into into a single option
         */
-       if (vp->da->type == FR_TYPE_STRUCT) {
-               fr_cursor_t child_cursor;
-               fr_pair_t *sorted = fr_cursor_current(cursor); /* NOT const */
-
-               fr_assert(vp->da == da);
-
-               fr_pair_list_sort(&sorted->vp_group, pair_sort_increasing);
-               fr_cursor_init(&child_cursor, &sorted->vp_group);
-
-               /*
-                *      Build the da_stack for the new structure.
-                */
-               vp = fr_cursor_head(&child_cursor);
-               fr_proto_da_stack_build(da_stack, vp ? vp->da : NULL);
-
+       if ((vp->da->type == FR_TYPE_STRUCT) || (da->type == FR_TYPE_STRUCT)) {
                slen = fr_struct_to_network(&work_dbuff, da_stack, depth, cursor, encoder_ctx, encode_value, encode_tlv);
                if (slen <= 0) return slen;
 
-               (void) fr_cursor_next(cursor); /* skip the VP containing the struct */
-
                /*
                 *      Rebuild the da_stack for the next option.
                 */
@@ -132,19 +108,6 @@ static ssize_t encode_value(fr_dbuff_t *dbuff,
                return fr_dbuff_set(dbuff, &work_dbuff);
        }
 
-       /*
-        *      If there's a struct on the da_stack, then the struct
-        *      members MUST be in a flat list.
-        */
-       if (da->type == FR_TYPE_STRUCT) {
-               slen = fr_struct_to_network(&work_dbuff, da_stack, depth, cursor, encoder_ctx, encode_value, encode_tlv);
-               if (slen <= 0) return slen;
-
-               vp = fr_cursor_current(cursor);
-               fr_proto_da_stack_build(da_stack, vp ? vp->da : NULL);
-               return fr_dbuff_set(dbuff, &work_dbuff);
-       }
-
        /*
         *      If it's not a TLV, it should be a value type RFC
         *      attribute make sure that it is.
index 2376514645cbb0259d6017d2598a7f9c526aae6d..8e84123caad53faacc86af4c5a223c8067ab8a8c 100644 (file)
@@ -393,29 +393,7 @@ static ssize_t encode_value(fr_dbuff_t *dbuff,
        /*
         *      This has special requirements.
         */
-       if (vp->da->type == FR_TYPE_STRUCT) {
-               fr_cursor_t child_cursor;
-
-               fr_assert(vp->da == da);
-
-               fr_cursor_init(&child_cursor, &vp->vp_group);
-
-               slen = fr_struct_to_network(&work_dbuff, da_stack, depth, &child_cursor, encoder_ctx, encode_value,
-                                           encode_tlv_hdr_internal);
-               if (slen <= 0) return slen;
-
-               /*
-                *      Skip the attribute we just encoded, and re-build the da_stack.
-                */
-               vp = fr_cursor_next(cursor);
-               fr_proto_da_stack_build(da_stack, vp ? vp->da : NULL);
-               return fr_dbuff_set(dbuff, &work_dbuff);
-       }
-
-       /*
-        *      Old-style struct fields in a flat list.
-        */
-       if (da->type == FR_TYPE_STRUCT) {
+       if ((vp->da->type == FR_TYPE_STRUCT) || (da->type == FR_TYPE_STRUCT)) {
                slen = fr_struct_to_network(&work_dbuff, da_stack, depth, cursor, encoder_ctx, encode_value,
                                            encode_tlv_hdr_internal);
                if (slen <= 0) return slen;