From 9d3ce87700b216eb3372c9b303dbe688b6e2d1fc Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Thu, 28 Jun 2018 11:04:47 +0930 Subject: [PATCH] decode_short_ids: move to common. We want to use it in devtools/decodemsg. Signed-off-by: Rusty Russell --- common/Makefile | 1 + common/decode_short_channel_ids.c | 62 ++++++++++++++++++++++++++ common/decode_short_channel_ids.h | 20 +++++++++ gossipd/Makefile | 1 + gossipd/gossip.c | 74 +------------------------------ 5 files changed, 85 insertions(+), 73 deletions(-) create mode 100644 common/decode_short_channel_ids.c create mode 100644 common/decode_short_channel_ids.h diff --git a/common/Makefile b/common/Makefile index 7ed75f638..da8d83d17 100644 --- a/common/Makefile +++ b/common/Makefile @@ -12,6 +12,7 @@ COMMON_SRC_NOGEN := \ common/cryptomsg.c \ common/daemon.c \ common/daemon_conn.c \ + common/decode_short_channel_ids.c \ common/derive_basepoints.c \ common/dev_disconnect.c \ common/features.c \ diff --git a/common/decode_short_channel_ids.c b/common/decode_short_channel_ids.c new file mode 100644 index 000000000..38547769a --- /dev/null +++ b/common/decode_short_channel_ids.c @@ -0,0 +1,62 @@ +#include +#include +#include +#include + +static u8 *unzlib(const tal_t *ctx, const u8 *encoded, size_t len) +{ + /* http://www.zlib.net/zlib_tech.html gives 1032:1 as worst-case, + * which is 67632120 bytes for us. But they're not encoding zeroes, + * and each scid must be unique. So 1MB is far more reasonable. */ + unsigned long unclen = 1024*1024; + int zerr; + u8 *unc = tal_arr(ctx, u8, unclen); + + zerr = uncompress(unc, &unclen, encoded, len); + if (zerr != Z_OK) + return tal_free(unc); + + /* Truncate and return. */ + tal_resize(&unc, unclen); + return unc; +} + +struct short_channel_id *decode_short_ids(const tal_t *ctx, const u8 *encoded) +{ + struct short_channel_id *scids; + size_t max = tal_len(encoded), n; + enum scid_encode_types type; + + /* BOLT #7: + * + * The receiver: + * - if the first byte of `encoded_short_ids` is not a known encoding + * type: + * - MAY fail the connection + * - if `encoded_short_ids` does not decode into a whole number of + * `short_channel_id`: + * - MAY fail the connection + */ + type = fromwire_u8(&encoded, &max); + switch (type) { + case SHORTIDS_ZLIB: + encoded = unzlib(tmpctx, encoded, max); + if (!encoded) + return NULL; + max = tal_len(encoded); + /* fall thru */ + case SHORTIDS_UNCOMPRESSED: + n = 0; + scids = tal_arr(ctx, struct short_channel_id, n); + while (max) { + tal_resize(&scids, n+1); + fromwire_short_channel_id(&encoded, &max, &scids[n++]); + } + + /* encoded is set to NULL if we ran over */ + if (!encoded) + return tal_free(scids); + return scids; + } + return NULL; +} diff --git a/common/decode_short_channel_ids.h b/common/decode_short_channel_ids.h new file mode 100644 index 000000000..e22e539a8 --- /dev/null +++ b/common/decode_short_channel_ids.h @@ -0,0 +1,20 @@ +#ifndef LIGHTNING_COMMON_DECODE_SHORT_CHANNEL_IDS_H +#define LIGHTNING_COMMON_DECODE_SHORT_CHANNEL_IDS_H +#include "config.h" +#include +#include + +/* BOLT #7: + * + * Encoding types: + * * `0`: uncompressed array of `short_channel_id` types, in ascending order. + * * `1`: array of `short_channel_id` types, in ascending order, compressed with + * zlib[1](#reference-1) + */ +enum scid_encode_types { + SHORTIDS_UNCOMPRESSED = 0, + SHORTIDS_ZLIB = 1 +}; + +struct short_channel_id *decode_short_ids(const tal_t *ctx, const u8 *encoded); +#endif /* LIGHTNING_COMMON_DECODE_SHORT_CHANNEL_IDS_H */ diff --git a/gossipd/Makefile b/gossipd/Makefile index cabbab3b1..77728c1ef 100644 --- a/gossipd/Makefile +++ b/gossipd/Makefile @@ -48,6 +48,7 @@ GOSSIPD_COMMON_OBJS := \ common/cryptomsg.o \ common/daemon.o \ common/daemon_conn.o \ + common/decode_short_channel_ids.o \ common/dev_disconnect.o \ common/features.o \ common/gen_status_wire.o \ diff --git a/gossipd/gossip.c b/gossipd/gossip.c index 9ae4c8928..a1f88ff75 100644 --- a/gossipd/gossip.c +++ b/gossipd/gossip.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -65,18 +66,6 @@ #define INITIAL_WAIT_SECONDS 1 #define MAX_WAIT_SECONDS 300 -/* BOLT #7: - * - * Encoding types: - * * `0`: uncompressed array of `short_channel_id` types, in ascending order. - * * `1`: array of `short_channel_id` types, in ascending order, compressed with - * zlib[1](#reference-1) - */ -enum scid_encode_types { - SHORTIDS_UNCOMPRESSED = 0, - SHORTIDS_ZLIB = 1 -}; - /* We put everything in this struct (redundantly) to pass it to timer cb */ struct important_peerid { struct daemon *daemon; @@ -880,67 +869,6 @@ static u8 *handle_gossip_msg(struct daemon *daemon, const u8 *msg, return NULL; } -static u8 *unzlib(const tal_t *ctx, const u8 *encoded, size_t len) -{ - /* http://www.zlib.net/zlib_tech.html gives 1032:1 as worst-case, - * which is 67632120 bytes for us. But they're not encoding zeroes, - * and each scid must be unique. So 1MB is far more reasonable. */ - unsigned long unclen = 1024*1024; - int zerr; - u8 *unc = tal_arr(ctx, u8, unclen); - - zerr = uncompress(unc, &unclen, encoded, len); - if (zerr != Z_OK) { - status_trace("unzlib: error %i", zerr); - return tal_free(unc); - } - - /* Truncate and return. */ - tal_resize(&unc, unclen); - return unc; -} - -static struct short_channel_id *decode_short_ids(const tal_t *ctx, - const u8 *encoded) -{ - struct short_channel_id *scids; - size_t max = tal_len(encoded), n; - enum scid_encode_types type; - - /* BOLT #7: - * - * The receiver: - * - if the first byte of `encoded_short_ids` is not a known encoding - * type: - * - MAY fail the connection - * - if `encoded_short_ids` does not decode into a whole number of - * `short_channel_id`: - * - MAY fail the connection - */ - type = fromwire_u8(&encoded, &max); - switch (type) { - case SHORTIDS_ZLIB: - encoded = unzlib(tmpctx, encoded, max); - if (!encoded) - return NULL; - max = tal_len(encoded); - /* fall thru */ - case SHORTIDS_UNCOMPRESSED: - n = 0; - scids = tal_arr(ctx, struct short_channel_id, n); - while (max) { - tal_resize(&scids, n+1); - fromwire_short_channel_id(&encoded, &max, &scids[n++]); - } - - /* encoded is set to NULL if we ran over */ - if (!encoded) - return tal_free(scids); - return scids; - } - return NULL; -} - static void handle_query_short_channel_ids(struct peer *peer, u8 *msg) { struct routing_state *rstate = peer->daemon->rstate;