mirror of
https://github.com/aljazceru/lightning.git
synced 2025-12-19 23:24:27 +01:00
common/tlvstream: allow fromwire_tlv to accept *any* unknown type.
This is used for keysend if EXPERIMENTAL_FEATURES is set. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include <ccan/array_size/array_size.h>
|
#include <ccan/array_size/array_size.h>
|
||||||
#include <ccan/asort/asort.h>
|
#include <ccan/asort/asort.h>
|
||||||
|
#include <ccan/cast/cast.h>
|
||||||
#include <ccan/tal/str/str.h>
|
#include <ccan/tal/str/str.h>
|
||||||
#include <common/json_tok.h>
|
#include <common/json_tok.h>
|
||||||
#include <common/memleak.h>
|
#include <common/memleak.h>
|
||||||
@@ -342,7 +343,7 @@ static struct command_result *htlc_accepted_call(struct command *cmd,
|
|||||||
struct out_req *req;
|
struct out_req *req;
|
||||||
struct timeabs now = time_now();
|
struct timeabs now = time_now();
|
||||||
const char *err;
|
const char *err;
|
||||||
u64 *allowed = tal_arr(cmd, u64, 1);
|
u64 *allowed;
|
||||||
size_t err_off;
|
size_t err_off;
|
||||||
u64 err_type;
|
u64 err_type;
|
||||||
|
|
||||||
@@ -360,8 +361,15 @@ static struct command_result *htlc_accepted_call(struct command *cmd,
|
|||||||
return htlc_accepted_continue(cmd, NULL);
|
return htlc_accepted_continue(cmd, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if EXPERIMENTAL_FEATURES
|
||||||
|
/* Note: This is a magic pointer value, not an actual array */
|
||||||
|
allowed = cast_const(u64 *, FROMWIRE_TLV_ANY_TYPE);
|
||||||
|
#else
|
||||||
/* We explicitly allow our type. */
|
/* We explicitly allow our type. */
|
||||||
allowed[0] = 5482373484;
|
allowed = tal_arr(cmd, u64, 1);
|
||||||
|
allowed[0] = PREIMAGE_TLV_TYPE;
|
||||||
|
#endif
|
||||||
|
|
||||||
payload = tlv_tlv_payload_new(cmd);
|
payload = tlv_tlv_payload_new(cmd);
|
||||||
if (!fromwire_tlv(&rawpayload, &max, tlvs_tlv_tlv_payload, TLVS_ARRAY_SIZE_tlv_tlv_payload,
|
if (!fromwire_tlv(&rawpayload, &max, tlvs_tlv_tlv_payload, TLVS_ARRAY_SIZE_tlv_tlv_payload,
|
||||||
payload, &payload->fields, allowed, &err_off, &err_type)) {
|
payload, &payload->fields, allowed, &err_off, &err_type)) {
|
||||||
@@ -380,6 +388,7 @@ static struct command_result *htlc_accepted_call(struct command *cmd,
|
|||||||
preimage_field = field;
|
preimage_field = field;
|
||||||
break;
|
break;
|
||||||
} else if (field->numtype % 2 == 0 && field->meta == NULL) {
|
} else if (field->numtype % 2 == 0 && field->meta == NULL) {
|
||||||
|
/* This can only happen with FROMWIRE_TLV_ANY_TYPE! */
|
||||||
unknown_field = field;
|
unknown_field = field;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -390,19 +399,10 @@ static struct command_result *htlc_accepted_call(struct command *cmd,
|
|||||||
return htlc_accepted_continue(cmd, NULL);
|
return htlc_accepted_continue(cmd, NULL);
|
||||||
|
|
||||||
if (unknown_field != NULL) {
|
if (unknown_field != NULL) {
|
||||||
#if !EXPERIMENTAL_FEATURES
|
|
||||||
plugin_log(cmd->plugin, LOG_UNUSUAL,
|
|
||||||
"Payload contains unknown even TLV-type %" PRIu64
|
|
||||||
", can't safely accept the keysend. Deferring to "
|
|
||||||
"other plugins.",
|
|
||||||
unknown_field->numtype);
|
|
||||||
return htlc_accepted_continue(cmd, NULL);
|
|
||||||
#else
|
|
||||||
plugin_log(cmd->plugin, LOG_INFORM,
|
plugin_log(cmd->plugin, LOG_INFORM,
|
||||||
"Experimental: Accepting the keysend payment "
|
"Experimental: Accepting the keysend payment "
|
||||||
"despite having unknown even TLV type %" PRIu64 ".",
|
"despite having unknown even TLV type %" PRIu64 ".",
|
||||||
unknown_field->numtype);
|
unknown_field->numtype);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If malformed (amt is compulsory), let lightningd handle it. */
|
/* If malformed (amt is compulsory), let lightningd handle it. */
|
||||||
|
|||||||
@@ -8,6 +8,11 @@
|
|||||||
#define SUPERVERBOSE(...)
|
#define SUPERVERBOSE(...)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* This simply needs to be an address which is neither NULL nor a
|
||||||
|
* tal_arr return */
|
||||||
|
static const u64 dummy;
|
||||||
|
const u64 *FROMWIRE_TLV_ANY_TYPE = &dummy;
|
||||||
|
|
||||||
static int tlv_field_cmp(const struct tlv_field *a, const struct tlv_field *b,
|
static int tlv_field_cmp(const struct tlv_field *a, const struct tlv_field *b,
|
||||||
void *x)
|
void *x)
|
||||||
{
|
{
|
||||||
@@ -117,6 +122,9 @@ static bool tlv_type_is_allowed(const struct tlv_field *f,
|
|||||||
if (f->numtype % 2 != 0)
|
if (f->numtype % 2 != 0)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
if (extra_types == FROMWIRE_TLV_ANY_TYPE)
|
||||||
|
return true;
|
||||||
|
|
||||||
/* Now iterate through the extras and see if we should make an
|
/* Now iterate through the extras and see if we should make an
|
||||||
* exception. */
|
* exception. */
|
||||||
for (size_t i = 0; i < tal_count(extra_types); i++)
|
for (size_t i = 0; i < tal_count(extra_types); i++)
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ struct tlv_field *tlv_make_fields_(const struct tlv_record_type *types,
|
|||||||
* @types / @num_types: table of known tlv types
|
* @types / @num_types: table of known tlv types
|
||||||
* @record: the tlv to hand to @type-specific decode
|
* @record: the tlv to hand to @type-specific decode
|
||||||
* @fields: the fields array to populate
|
* @fields: the fields array to populate
|
||||||
* @extra_types: tal_arr or NULL of unknown types to allow
|
* @extra_types: tal_arr of unknown types to allow, or NULL, or FROMWIRE_TLV_ANY_TYPE.
|
||||||
* @err_off: NULL, or set to offset in tlv stream which failed.
|
* @err_off: NULL, or set to offset in tlv stream which failed.
|
||||||
* @err_type: NULL, or set to tlv type which failed (or 0 if malformed)
|
* @err_type: NULL, or set to tlv type which failed (or 0 if malformed)
|
||||||
*/
|
*/
|
||||||
@@ -61,6 +61,9 @@ void towire_tlv(u8 **pptr,
|
|||||||
* tlv malformed) */
|
* tlv malformed) */
|
||||||
size_t tlv_field_offset(const u8 *tlvstream, size_t tlvlen, u64 fieldtype);
|
size_t tlv_field_offset(const u8 *tlvstream, size_t tlvlen, u64 fieldtype);
|
||||||
|
|
||||||
|
/* Constant for fromwire_tlv to allow absolutely any unknown type. */
|
||||||
|
extern const u64 *FROMWIRE_TLV_ANY_TYPE;
|
||||||
|
|
||||||
/* Generic primitive setters for tlvstreams. */
|
/* Generic primitive setters for tlvstreams. */
|
||||||
void tlvstream_set_raw(struct tlv_field **stream, u64 type, void *value TAKES, size_t valuelen);
|
void tlvstream_set_raw(struct tlv_field **stream, u64 type, void *value TAKES, size_t valuelen);
|
||||||
void tlvstream_set_short_channel_id(struct tlv_field **stream, u64 type,
|
void tlvstream_set_short_channel_id(struct tlv_field **stream, u64 type,
|
||||||
|
|||||||
Reference in New Issue
Block a user