]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
convert dhcpv6 to use iterator
authorJames Jones <jejones3141@gmail.com>
Wed, 1 Apr 2020 18:10:33 +0000 (13:10 -0500)
committerAlan DeKok <aland@freeradius.org>
Wed, 1 Apr 2020 21:03:56 +0000 (17:03 -0400)
src/protocols/dhcpv6/base.c
src/protocols/dhcpv6/encode.c

index e5c1aafc1197c8d5583e86484b57ef1fb2999f01..ebecb56837a024eddec95cdd5c36d715c317c733 100644 (file)
@@ -507,6 +507,30 @@ ssize_t    fr_dhcpv6_decode(TALLOC_CTX *ctx, uint8_t const *packet, size_t packet_l
        return packet_len;
 }
 
+/** DHCPV6-specific iterator
+ *
+ */
+static void *fr_dhcpv6_next_encodable(void **prev, void *to_eval, void *uctx)
+{
+       VALUE_PAIR      *c, *p;
+       fr_dict_t       *dict = talloc_get_type_abort(uctx, fr_dict_t);
+
+       if (!to_eval) return NULL;
+
+       for (p = *prev, c = to_eval; c; p = c, c = c->next) {
+               VP_VERIFY(c);
+               if (c->da->dict != dict || c->da->flags.internal) continue;
+               if (c->da->type == FR_TYPE_BOOL && !c->vp_bool) continue;
+
+               break;
+       }
+
+       *prev = p;
+
+       return c;
+}
+
+
 
 /** Encode a DHCPv6 packet
  *
@@ -560,7 +584,7 @@ ssize_t     fr_dhcpv6_encode(uint8_t *packet, size_t packet_len, uint8_t const *orig
 
        packet_ctx.root = root;
 
-       fr_cursor_init(&cursor, &vps);
+       fr_cursor_talloc_iter_init(&cursor, &vps, fr_dhcpv6_next_encodable, dict_dhcpv6, VALUE_PAIR);
        p = packet + 4;
        end = packet + packet_len;
 
index 68951c61a06d68e25ff96a2706300db6633c53e4..fdbc98301158ab13cd7e88c7d8e6f8a59d008da5 100644 (file)
@@ -50,54 +50,6 @@ static ssize_t encode_tlv_hdr(uint8_t *out, size_t outlen,
                              fr_da_stack_t *da_stack, unsigned int depth,
                              fr_cursor_t *cursor, void *encoder_ctx);
 
-static inline bool is_encodable(fr_dict_attr_t const *root, VALUE_PAIR const *vp)
-{
-       if (!vp) return false;
-       if (vp->da->flags.internal) return false;
-       if (!fr_dict_parent_common(root, vp->da, true)) return false;
-
-       /*
-        *      False bools are represented by the absence of
-        *      an option, i.e. only bool attributes which are
-        *      true get encoded.
-        */
-       if ((vp->da->type == FR_TYPE_BOOL) && !vp->vp_bool) return false;
-
-       return true;
-}
-
-/** Find the next attribute to encode
- *
- * @param cursor to iterate over.
- * @param encoder_ctx the context for the encoder
- * @return encodable VALUE_PAIR, or NULL if none available.
- */
-static inline VALUE_PAIR *next_encodable(fr_cursor_t *cursor, void *encoder_ctx)
-{
-       VALUE_PAIR              *vp;
-       fr_dhcpv6_encode_ctx_t  *packet_ctx = encoder_ctx;
-
-       do { vp = fr_cursor_next(cursor); } while (vp && !is_encodable(packet_ctx->root, vp));
-       return fr_cursor_current(cursor);
-}
-
-/** Determine if the current attribute is encodable, or find the first one that is
- *
- * @param cursor to iterate over.
- * @param encoder_ctx the context for the encoder
- * @return encodable VALUE_PAIR, or NULL if none available.
- */
-static inline VALUE_PAIR *first_encodable(fr_cursor_t *cursor, void *encoder_ctx)
-{
-       VALUE_PAIR              *vp;
-       fr_dhcpv6_encode_ctx_t  *packet_ctx = encoder_ctx;
-
-       vp = fr_cursor_current(cursor);
-       if (is_encodable(packet_ctx->root, vp)) return vp;
-
-       return next_encodable(cursor, encoder_ctx);
-}
-
 /** Macro-like function for encoding an option header
  *
  *    0                   1                   2                   3
@@ -169,22 +121,18 @@ static ssize_t encode_value(uint8_t *out, size_t outlen,
         *      Pack multiple attributes into into a single option
         */
        if (da->type == FR_TYPE_STRUCT) {
-               fr_dhcpv6_encode_ctx_t  *packet_ctx = encoder_ctx;
-
                slen = encode_struct(out, outlen, da_stack, depth, cursor, encoder_ctx);
                if (slen < 0) return slen;
 
                /*
                 *      The encode_struct() routine eats all relevant
                 *      VPs.  It stops when the cursor is pointing to
-                *      a VP which is *not* part of the struct.  As a
-                *      result, we shouldn't call next_encodable()
-                *      here unless the next VP isn't encodable.
+                *      a VP which is *not* part of the struct... but
+                *      with the move to an iterator, whatever that is
+                *      will be encodable; the iterator filters out
+                *      anything that isn't.
                 */
                vp = fr_cursor_current(cursor);
-               if (!is_encodable(packet_ctx->root, vp)) {
-                       vp = next_encodable(cursor, packet_ctx);
-               }
                fr_proto_da_stack_build(da_stack, vp ? vp->da : NULL);
                return slen;
        }
@@ -475,7 +423,7 @@ static ssize_t encode_value(uint8_t *out, size_t outlen,
        /*
         *      Rebuilds the TLV stack for encoding the next attribute
         */
-       vp = next_encodable(cursor, encoder_ctx);
+       vp = fr_cursor_next(cursor);
        fr_proto_da_stack_build(da_stack, vp ? vp->da : NULL);
 
        return p - out;
@@ -513,7 +461,7 @@ static inline ssize_t encode_array(uint8_t *out, size_t outlen,
                        if (slen <= 0) return PAIR_ENCODE_FATAL_ERROR;
 
                        p += slen;
-                       vp = next_encodable(cursor, encoder_ctx);
+                       vp = fr_cursor_next(cursor);
                        if (!vp || (vp->da != da)) break;               /* Stop if we have an attribute of a different type */
                }
 
@@ -834,7 +782,7 @@ ssize_t fr_dhcpv6_encode_option(uint8_t *out, size_t outlen, fr_cursor_t *cursor
        fr_da_stack_t           da_stack;
        ssize_t                 slen;
 
-       vp = first_encodable(cursor, encoder_ctx);
+       vp = fr_cursor_current(cursor);
        if (!vp) return 0;
 
        if (vp->da->flags.internal) {