fr_dict_t const *dict_radius;
fr_dict_attr_t const *attr_radius;
fr_dict_attr_t const *da;
+ TALLOC_CTX *tmp_ctx = NULL;
dict_radius = fr_dict_by_protocol_name("radius");
fr_assert(dict_radius != NULL);
fr_strerror_printf("Malformed diameter attribute at offset %zu. Needed at least 8 bytes, got %zu bytes",
p - data, end - p);
error:
+ talloc_free(tmp_ctx);
fr_dcursor_free_list(cursor);
return -1;
}
goto error;
}
- MEM(da = fr_dict_unknown_afrom_fields(vp, attr_vendor_specific, vendor, attr));
- goto reinit;
+ if (!tmp_ctx) {
+ fr_dict_attr_t *n;
+
+ MEM(our_parent = n = fr_dict_unknown_vendor_afrom_num(ctx, parent, vendor));
+ tmp_ctx = n;
+ } else {
+ MEM(our_parent = fr_dict_unknown_vendor_afrom_num(tmp_ctx, parent, vendor));
+ }
}
} else {
our_parent = attr_radius;
goto error;
}
- MEM(da = fr_dict_unknown_attr_afrom_num(vp, parent, attr));
+ MEM(da = fr_dict_unknown_attr_afrom_num(vp, our_parent, attr));
reinit:
if (fr_pair_reinit_from_da(NULL, vp, da) < 0) {
/*
* We got this far. It looks OK.
*/
+ talloc_free(tmp_ctx);
return p - data;
}
vendor_child = fr_dict_attr_child_by_num(parent, vendor);
if (!vendor_child) {
/*
- * If there's no child, it means the vendor is unknown
- * which means the child attribute is unknown too.
- *
- * fr_dict_unknown_afrom_fields will do the right thing
- * and create both an unknown vendor and an unknown
- * attr.
- *
- * This can be used later by the encoder to rebuild
- * the attribute header.
+ * If there's no child, it means the vendor is unknown. Create a
+ * temporary vendor in the packet_ctx. This will be cleaned up when the
+ * decoder exists, which is fine. Because any unknown attributes which
+ * depend on it will copy the entire hierarchy.
*/
- vendor_child = fr_dict_unknown_afrom_fields(packet_ctx->tmp_ctx, parent, vendor, p[4]);
- if (!vendor_child) {
- fr_strerror_printf_push("decoder failed creating unknown attribute in %s",
- parent->name);
- return -1;
- }
- parent = vendor_child;
- p += 5;
- data_len -= 5;
- break;
+ vendor_child = fr_dict_unknown_vendor_afrom_num(packet_ctx->tmp_ctx, parent, vendor);
+ if (!vendor_child) return PAIR_DECODE_OOM;
}
child = fr_dict_attr_child_by_num(vendor_child, p[4]);
/*
* Vendor exists but child didn't, create an unknown child.
*/
- child = fr_dict_unknown_attr_afrom_num(packet_ctx->tmp_ctx, parent, p[4]);
+ child = fr_dict_unknown_attr_afrom_num(packet_ctx->tmp_ctx, vendor_child, p[4]);
if (!child) {
fr_strerror_printf_push("decoder failed creating unknown attribute in %s",
parent->name);