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);
+}
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
}
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;
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;
}
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;
}
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;
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) {
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
}
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.
* 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;
/*
#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
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
*
* 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;
/*
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.
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;
/*
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);
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;
/*
* 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;
/*
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.
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;
/*
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;
}
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++;