From 6df67897441942181bf4a2afcb6bb79c0c5fa08d Mon Sep 17 00:00:00 2001 From: Aditya Sharma Date: Fri, 21 Feb 2025 00:24:12 +0530 Subject: [PATCH] Enable Length-Prefixed TLVs through Generator This change allows adding a length prefix to a serialized TLV. It will be particularly useful for serializing all 'scb_chan' entries in the 'emergency.recover' file. Key Changes: - Removed the need to loop in towire_tlv and fromwire_tlv, so the if conditions have been modified accordingly. - During serialization, the length of the TLV is calculated before appending it, and it is stored in a temporary variable. - For fromwire_tlv, only a simple length adjustment is required, and no loop is needed here either. --- tools/gen/header_template | 2 +- tools/gen/impl_template | 15 ++++++++++++--- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/tools/gen/header_template b/tools/gen/header_template index bbfe0df97..5ceb9df32 100644 --- a/tools/gen/header_template +++ b/tools/gen/header_template @@ -70,7 +70,7 @@ struct ${struct.struct_name()} { % if bool(f.len_field_of): <% continue %> % endif - % if f.is_varlen() and f.type_obj.is_varsize(): + % if not f.type_obj.is_tlv() and f.is_varlen() and f.type_obj.is_varsize(): ${f.type_obj.type_name()} **${f.name}; % elif f.is_varlen() or f.type_obj.is_varsize(): ${f.type_obj.type_name()} *${f.name}; diff --git a/tools/gen/impl_template b/tools/gen/impl_template index 7b9011e1d..c3b97d5f5 100644 --- a/tools/gen/impl_template +++ b/tools/gen/impl_template @@ -51,7 +51,7 @@ bool ${enum_set['name']}_is_defined(u16 type) ## START PARTIALS ## Subtype and TLV-msg towire_ <%def name="towire_subtype_field(fieldname, f, type_obj, is_single_ptr, ptr)">\ -% if f.is_array() or f.is_varlen(): +% if not f.type_obj.is_tlv() and (f.is_array() or f.is_varlen()): % if type_obj.has_array_helper(): towire_${type_obj.name}_array(${ptr}, ${fieldname}, ${f.size('tal_count(' + fieldname + ')')}); % else: @@ -82,7 +82,7 @@ towire_${type_obj.name}(${ptr}, ${'' if type_obj.is_assignable() or type_obj.is_ if f.type_obj.is_varsize(): typename += ' *' %>\ -% if f.is_array() or f.is_varlen(): +% if not f.type_obj.is_tlv() and (f.is_array() or f.is_varlen()): % if f.type_obj.has_array_helper(): ## We assume array helpers only deal with things literally transcribed!! % if f.is_varlen(): @@ -116,8 +116,10 @@ ${fieldname} = ${f.size('*plen')} ? tal_arr(${ctx}, ${typename}, 0) : NULL; % endif % if f.type_obj.is_assignable(): ${ f.name if f.len_field_of else fieldname} = fromwire_${type_}(cursor, plen); - % elif f.type_obj.is_varsize(): + % elif f.type_obj.is_varsize() and not f.type_obj.is_tlv(): ${fieldname} = fromwire_${type_}(${ctx}, cursor, plen); + % elif f.type_obj.is_tlv() and f.is_varlen(): +${fieldname} = fromwire_${type_}(${ctx}, cursor, &(size_t){(size_t)${f.size()}}); % else: fromwire_${type_}(cursor, plen, &${fieldname}); % endif @@ -138,7 +140,14 @@ fromwire_${type_}(cursor, plen, &${fieldname}); ${static}void towire_${subtype.name}(u8 **p, const ${subtype.type_name()} *${subtype.name}) { % for f in subtype.get_len_fields(): + % if not subtype.find_data_field(f.len_field_of).type_obj.is_tlv(): # Check if this signify length of TLV. ${f.type_obj.type_name()} ${f.name} = tal_count(${subtype.name}->${f.len_field_of}); + % else: + /* Length of serialized tlv. */ + u8 *tmp = tal_arr(tmpctx, u8, 0); + towire_tlv_${subtype.find_data_field(f.len_field_of).type_obj.name}(&tmp, ${subtype.name}->${f.len_field_of}); + ${f.type_obj.type_name()} ${f.name} = tal_bytelen(tmp); + % endif % endfor % for f in subtype.fields.values():