diff --git a/tools/gen/header_template b/tools/gen/header_template index b1e492fb7..019b2b288 100644 --- a/tools/gen/header_template +++ b/tools/gen/header_template @@ -53,6 +53,11 @@ struct ${struct.struct_name()} { ## Structs for TLVs % for tlv in tlvs.values(): struct ${tlv.struct_name()} { + /* Raw fields including unknown ones. */ + struct tlv_field *fields; + + /* TODO The following explicit fields could just point into the + * tlv_field entries above to save on memory. */ % for msg in tlv.messages.values(): struct ${msg.struct_name()} *${msg.name}; % endfor diff --git a/tools/gen/impl_template b/tools/gen/impl_template index 169f0332d..eefdd5ace 100644 --- a/tools/gen/impl_template +++ b/tools/gen/impl_template @@ -157,7 +157,11 @@ fromwire_${type_}(${'ctx, ' if f.needs_context() else ''}&cursor, &plen, ${'*' i ${tlv.type_name()} *${tlv.struct_name()}_new(const tal_t *ctx) { /* Initialize everything to NULL. (Quiet, C pedants!) */ - return talz(ctx, struct ${tlv.struct_name()}); + ${tlv.type_name()} *inst = talz(ctx, struct ${tlv.struct_name()}); + + /* Initialized the fields to an empty array. */ + inst->fields = tal_arr(inst, struct tlv_field, 0); + return inst; } % for msg in tlv.messages.values(): diff --git a/wire/tlvstream.h b/wire/tlvstream.h index c7f033f0b..f36d42c23 100644 --- a/wire/tlvstream.h +++ b/wire/tlvstream.h @@ -15,6 +15,19 @@ struct tlv_record_type { void (*fromwire)(const u8 **cursor, size_t *max, void *record); }; +/* A single TLV field, consisting of the data and its associated metadata. */ +struct tlv_field { + /* If this is a type that is known to c-lightning we have a pointer to + * the metadata. */ + const struct tlv_record_type *meta; + + /* In any case we'll have the numeric type, even if we don't have a + * name that we can call it. */ + u64 numtype; + size_t length; + u8 *value; +}; + /* Pull all tlvs from a stream. Return false and calls fromwire_fail() on * error. */ bool fromwire_tlvs(const u8 **cursor, size_t *max,