diff --git a/common/Makefile b/common/Makefile index 9ea159cb8..5290afe19 100644 --- a/common/Makefile +++ b/common/Makefile @@ -32,6 +32,7 @@ COMMON_SRC := \ common/utils.c \ common/utxo.c \ common/version.c \ + common/wireaddr.c \ common/wire_error.c \ common/withdraw_tx.c diff --git a/common/json.h b/common/json.h index badf3bf93..b0501b6d0 100644 --- a/common/json.h +++ b/common/json.h @@ -10,7 +10,6 @@ #define JSMN_STRICT 1 # include -struct ipaddr; struct json_result; struct short_channel_id; diff --git a/common/wireaddr.c b/common/wireaddr.c new file mode 100644 index 000000000..784f304f0 --- /dev/null +++ b/common/wireaddr.c @@ -0,0 +1,30 @@ +#include +#include + +/* Returns false if we didn't parse it, and *cursor == NULL if malformed. */ +bool fromwire_wireaddr(const u8 **cursor, size_t *max, struct wireaddr *addr) +{ + addr->type = fromwire_u8(cursor, max); + + switch (addr->type) { + case ADDR_TYPE_IPV4: + addr->addrlen = 4; + break; + case ADDR_TYPE_IPV6: + addr->addrlen = 16; + break; + default: + return false; + } + fromwire(cursor, max, addr->addr, addr->addrlen); + addr->port = fromwire_u16(cursor, max); + + return *cursor != NULL; +} + +void towire_wireaddr(u8 **pptr, const struct wireaddr *addr) +{ + towire_u8(pptr, addr->type); + towire(pptr, addr->addr, addr->addrlen); + towire_u16(pptr, addr->port); +} diff --git a/common/wireaddr.h b/common/wireaddr.h new file mode 100644 index 000000000..ae196b9cc --- /dev/null +++ b/common/wireaddr.h @@ -0,0 +1,41 @@ +#ifndef LIGHTNING_COMMON_WIREADDR_H +#define LIGHTNING_COMMON_WIREADDR_H +#include "config.h" +#include +#include +#include + +/* BOLT #7: + * + * The following `address descriptor` types are defined: + * + * * `0`: padding. data = none (length 0). + * * `1`: ipv4. data = `[4:ipv4_addr][2:port]` (length 6) + * * `2`: ipv6. data = `[16:ipv6_addr][2:port]` (length 18) + * * `3`: tor v2 onion service. data = `[10:onion_addr][2:port]` (length 12) + * * Version 2 onion service addresses. Encodes an 80-bit truncated `SHA-1` hash + * of a 1024-bit `RSA` public key for the onion service. + * * `4`: tor v3 onion service. data `[35:onion_addr][2:port]` (length 37) + * * Version 3 ([prop224](https://gitweb.torproject.org/torspec.git/tree/proposals/224-rend-spec-ng.txt)) + * onion service addresses. Encodes: `[32:32_byte_ed25519_pubkey] || [2:checksum] || [1:version]`. + * where `checksum = sha3(".onion checksum" | pubkey || version)[:2]` + */ + +enum wire_addr_type { + ADDR_TYPE_PADDING = 0, + ADDR_TYPE_IPV4 = 1, + ADDR_TYPE_IPV6 = 2, +}; + +/* FIXME(cdecker) Extend this once we have defined how TOR addresses + * should look like */ +struct wireaddr { + enum wire_addr_type type; + u8 addrlen; + u8 addr[16]; + u16 port; +}; + +void towire_wireaddr(u8 **pptr, const struct wireaddr *addr); +bool fromwire_wireaddr(const u8 **cursor, size_t *max, struct wireaddr *addr); +#endif /* LIGHTNING_COMMON_WIREADDR_H */ diff --git a/gossipd/Makefile b/gossipd/Makefile index 26b8e60e7..2111ed346 100644 --- a/gossipd/Makefile +++ b/gossipd/Makefile @@ -49,6 +49,7 @@ GOSSIPD_COMMON_OBJS := \ common/type_to_string.o \ common/utils.o \ common/version.o \ + common/wireaddr.o \ common/wire_error.o \ hsmd/client.o \ hsmd/gen_hsm_client_wire.o \ diff --git a/gossipd/gossip.c b/gossipd/gossip.c index ac9f1fe58..b48edd43b 100644 --- a/gossipd/gossip.c +++ b/gossipd/gossip.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -83,7 +84,7 @@ struct reaching { struct pubkey id; /* Where I'm reaching to. */ - struct ipaddr addr; + struct wireaddr addr; /* Did we succeed? */ bool succeeded; @@ -99,7 +100,7 @@ struct peer { struct pubkey id; /* Where it's connected to. */ - struct ipaddr addr; + struct wireaddr addr; /* Feature bitmaps. */ u8 *gfeatures, *lfeatures; @@ -147,7 +148,7 @@ struct addrhint { struct pubkey id; /* FIXME: use array... */ - struct ipaddr addr; + struct wireaddr addr; }; /* FIXME: Reorder */ @@ -194,7 +195,7 @@ static struct addrhint *find_addrhint(struct daemon *daemon, static struct peer *new_peer(const tal_t *ctx, struct daemon *daemon, const struct pubkey *their_id, - const struct ipaddr *addr, + const struct wireaddr *addr, const struct crypto_state *cs) { struct peer *peer = tal(ctx, struct peer); @@ -342,7 +343,7 @@ static struct io_plan *read_init(struct io_conn *conn, struct peer *peer) * we have the features. */ static struct io_plan *init_new_peer(struct io_conn *conn, const struct pubkey *their_id, - const struct ipaddr *addr, + const struct wireaddr *addr, const struct crypto_state *cs, struct daemon *daemon) { @@ -718,7 +719,7 @@ static struct io_plan *handle_peer(struct io_conn *conn, struct daemon *daemon, struct peer *peer; struct crypto_state cs; struct pubkey id; - struct ipaddr addr; + struct wireaddr addr; u8 *gfeatures, *lfeatures; u8 *inner_msg; @@ -949,7 +950,7 @@ fail: static struct io_plan *connection_in(struct io_conn *conn, struct daemon *daemon) { - struct ipaddr addr; + struct wireaddr addr; struct sockaddr_storage s; socklen_t len = sizeof(s); @@ -1112,7 +1113,7 @@ static void handle_forwarded_msg(struct io_conn *conn, struct daemon *daemon, co static struct io_plan *handshake_out_success(struct io_conn *conn, const struct pubkey *id, - const struct ipaddr *addr, + const struct wireaddr *addr, const struct crypto_state *cs, struct reaching *reach) { diff --git a/gossipd/gossip_wire.csv b/gossipd/gossip_wire.csv index eafdc7217..020d1cdc6 100644 --- a/gossipd/gossip_wire.csv +++ b/gossipd/gossip_wire.csv @@ -1,4 +1,5 @@ #include +#include # Initialize the gossip daemon. gossipctl_init,3000 @@ -15,7 +16,7 @@ gossipctl_init,,lfeatures,lflen*u8 # Master -> gossipd: Optional hint for where to find peer. gossipctl_peer_addrhint,3014 gossipctl_peer_addrhint,,id,struct pubkey -gossipctl_peer_addrhint,,addr,struct ipaddr +gossipctl_peer_addrhint,,addr,struct wireaddr # Master -> gossipd: connect to a peer. We may get a peer_connected. gossipctl_reach_peer,3001 @@ -24,7 +25,7 @@ gossipctl_reach_peer,,id,struct pubkey # Gossipd -> master: we got a peer. Two fds: peer and gossip gossip_peer_connected,3002 gossip_peer_connected,,id,struct pubkey -gossip_peer_connected,,addr,struct ipaddr +gossip_peer_connected,,addr,struct wireaddr gossip_peer_connected,,crypto_state,struct crypto_state gossip_peer_connected,,gflen,u16 gossip_peer_connected,,gfeatures,gflen*u8 @@ -34,7 +35,7 @@ gossip_peer_connected,,lfeatures,lflen*u8 # Gossipd -> master: peer sent non-gossip packet. Two fds: peer and gossip gossip_peer_nongossip,3003 gossip_peer_nongossip,,id,struct pubkey -gossip_peer_nongossip,,addr,struct ipaddr +gossip_peer_nongossip,,addr,struct wireaddr gossip_peer_nongossip,,crypto_state,struct crypto_state gossip_peer_nongossip,,gflen,u16 gossip_peer_nongossip,,gfeatures,gflen*u8 @@ -49,7 +50,7 @@ gossipctl_release_peer,,id,struct pubkey # Gossipd -> master: reply to gossip_release_peer. Two fds: peer and gossip. gossipctl_release_peer_reply,3104 -gossipctl_release_peer_reply,,addr,struct ipaddr +gossipctl_release_peer_reply,,addr,struct wireaddr gossipctl_release_peer_reply,,crypto_state,struct crypto_state gossipctl_release_peer_reply,,gflen,u16 gossipctl_release_peer_reply,,gfeatures,gflen*u8 @@ -62,7 +63,7 @@ gossipctl_release_peer_replyfail,3204 # Gossipd -> master: take over peer, with optional msg. (+peer fd) gossipctl_handle_peer,3013 gossipctl_handle_peer,,id,struct pubkey -gossipctl_handle_peer,,addr,struct ipaddr +gossipctl_handle_peer,,addr,struct wireaddr gossipctl_handle_peer,,crypto_state,struct crypto_state gossipctl_handle_peer,,gflen,u16 gossipctl_handle_peer,,gfeatures,gflen*u8 diff --git a/gossipd/handshake.c b/gossipd/handshake.c index 7cefb2df9..7a61e5d85 100644 --- a/gossipd/handshake.c +++ b/gossipd/handshake.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -171,7 +172,7 @@ struct handshake { struct act_three act3; /* Where is connection from/to */ - struct ipaddr addr; + struct wireaddr addr; /* Who we are */ struct pubkey my_id; @@ -184,7 +185,7 @@ struct handshake { /* Function to call once handshake complete. */ struct io_plan *(*cb)(struct io_conn *conn, const struct pubkey *their_id, - const struct ipaddr *ipaddr, + const struct wireaddr *wireaddr, const struct crypto_state *cs, void *cbarg); void *cbarg; @@ -353,12 +354,12 @@ static struct io_plan *handshake_succeeded(struct io_conn *conn, struct crypto_state cs; struct io_plan *(*cb)(struct io_conn *conn, const struct pubkey *their_id, - const struct ipaddr *addr, + const struct wireaddr *addr, const struct crypto_state *cs, void *cbarg); void *cbarg; struct pubkey their_id; - struct ipaddr addr; + struct wireaddr addr; /* BOLT #8: * @@ -961,10 +962,10 @@ static struct io_plan *act_one_responder(struct io_conn *conn, struct io_plan *responder_handshake_(struct io_conn *conn, const struct pubkey *my_id, - const struct ipaddr *addr, + const struct wireaddr *addr, struct io_plan *(*cb)(struct io_conn *, const struct pubkey *, - const struct ipaddr *, + const struct wireaddr *, const struct crypto_state *, void *cbarg), void *cbarg) @@ -983,10 +984,10 @@ struct io_plan *responder_handshake_(struct io_conn *conn, struct io_plan *initiator_handshake_(struct io_conn *conn, const struct pubkey *my_id, const struct pubkey *their_id, - const struct ipaddr *addr, + const struct wireaddr *addr, struct io_plan *(*cb)(struct io_conn *, const struct pubkey *, - const struct ipaddr *, + const struct wireaddr *, const struct crypto_state *, void *cbarg), void *cbarg) diff --git a/gossipd/handshake.h b/gossipd/handshake.h index 343dc501b..4ecc988e0 100644 --- a/gossipd/handshake.h +++ b/gossipd/handshake.h @@ -5,7 +5,7 @@ struct crypto_state; struct io_conn; -struct ipaddr; +struct wireaddr; struct pubkey; #define initiator_handshake(conn, my_id, their_id, addr, cb, cbarg) \ @@ -14,7 +14,7 @@ struct pubkey; (cb), (cbarg), \ struct io_conn *, \ const struct pubkey *, \ - const struct ipaddr *, \ + const struct wireaddr *, \ const struct crypto_state *), \ (cbarg)) @@ -22,10 +22,10 @@ struct pubkey; struct io_plan *initiator_handshake_(struct io_conn *conn, const struct pubkey *my_id, const struct pubkey *their_id, - const struct ipaddr *addr, + const struct wireaddr *addr, struct io_plan *(*cb)(struct io_conn *, const struct pubkey *, - const struct ipaddr *, + const struct wireaddr *, const struct crypto_state *, void *cbarg), void *cbarg); @@ -37,16 +37,16 @@ struct io_plan *initiator_handshake_(struct io_conn *conn, (cb), (cbarg), \ struct io_conn *, \ const struct pubkey *, \ - const struct ipaddr *, \ + const struct wireaddr *, \ const struct crypto_state *), \ (cbarg)) struct io_plan *responder_handshake_(struct io_conn *conn, const struct pubkey *my_id, - const struct ipaddr *addr, + const struct wireaddr *addr, struct io_plan *(*cb)(struct io_conn *, const struct pubkey *, - const struct ipaddr *, + const struct wireaddr *, const struct crypto_state *, void *cbarg), void *cbarg); diff --git a/gossipd/routing.c b/gossipd/routing.c index e51ef4992..1661e67d1 100644 --- a/gossipd/routing.c +++ b/gossipd/routing.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include @@ -79,7 +80,7 @@ static struct node *new_node(struct routing_state *rstate, n->alias = NULL; n->node_announcement = NULL; n->last_timestamp = -1; - n->addresses = tal_arr(n, struct ipaddr, 0); + n->addresses = tal_arr(n, struct wireaddr, 0); node_map_add(rstate->nodes, n); tal_add_destructor(n, destroy_node); @@ -628,14 +629,14 @@ void handle_channel_update(struct routing_state *rstate, const u8 *update, size_ tal_free(tmpctx); } -static struct ipaddr *read_addresses(const tal_t *ctx, const u8 *ser) +static struct wireaddr *read_addresses(const tal_t *ctx, const u8 *ser) { const u8 *cursor = ser; size_t max = tal_len(ser); - struct ipaddr *ipaddrs = tal_arr(ctx, struct ipaddr, 0); + struct wireaddr *wireaddrs = tal_arr(ctx, struct wireaddr, 0); int numaddrs = 0; while (cursor && cursor < ser + max) { - struct ipaddr ipaddr; + struct wireaddr wireaddr; /* Skip any padding */ while (max && cursor[0] == ADDR_TYPE_PADDING) @@ -647,19 +648,19 @@ static struct ipaddr *read_addresses(const tal_t *ctx, const u8 *ser) * descriptor` which does not match the types defined * above. */ - if (!fromwire_ipaddr(&cursor, &max, &ipaddr)) { + if (!fromwire_wireaddr(&cursor, &max, &wireaddr)) { if (!cursor) /* Parsing address failed */ - return tal_free(ipaddrs); + return tal_free(wireaddrs); /* Unknown type, stop there. */ break; } - tal_resize(&ipaddrs, numaddrs+1); - ipaddrs[numaddrs] = ipaddr; + tal_resize(&wireaddrs, numaddrs+1); + wireaddrs[numaddrs] = wireaddr; numaddrs++; } - return ipaddrs; + return wireaddrs; } void handle_node_announcement( @@ -675,7 +676,7 @@ void handle_node_announcement( u8 alias[32]; u8 *features, *addresses; const tal_t *tmpctx = tal_tmpctx(rstate); - struct ipaddr *ipaddrs; + struct wireaddr *wireaddrs; serialized = tal_dup_arr(tmpctx, u8, node_ann, len, 0); if (!fromwire_node_announcement(tmpctx, serialized, NULL, @@ -708,14 +709,14 @@ void handle_node_announcement( return; } - ipaddrs = read_addresses(tmpctx, addresses); - if (!ipaddrs) { + wireaddrs = read_addresses(tmpctx, addresses); + if (!wireaddrs) { status_trace("Unable to parse addresses."); tal_free(serialized); return; } tal_free(node->addresses); - node->addresses = tal_steal(node, ipaddrs); + node->addresses = tal_steal(node, wireaddrs); node->last_timestamp = timestamp; diff --git a/gossipd/routing.h b/gossipd/routing.h index b3e562b25..6139a946a 100644 --- a/gossipd/routing.h +++ b/gossipd/routing.h @@ -46,7 +46,7 @@ struct node { s64 last_timestamp; /* IP/Hostname and port of this node (may be NULL) */ - struct ipaddr *addresses; + struct wireaddr *addresses; /* Routes connecting to us, from us. */ struct node_connection **in, **out; diff --git a/gossipd/test/run-find_route-specific.c b/gossipd/test/run-find_route-specific.c index 247376db6..3581a543a 100644 --- a/gossipd/test/run-find_route-specific.c +++ b/gossipd/test/run-find_route-specific.c @@ -25,15 +25,15 @@ bool fromwire_channel_announcement(const tal_t *ctx UNNEEDED, const void *p UNNE /* Generated stub for fromwire_channel_update */ bool fromwire_channel_update(const void *p UNNEEDED, size_t *plen UNNEEDED, secp256k1_ecdsa_signature *signature UNNEEDED, struct sha256_double *chain_hash UNNEEDED, struct short_channel_id *short_channel_id UNNEEDED, u32 *timestamp UNNEEDED, u16 *flags UNNEEDED, u16 *cltv_expiry_delta UNNEEDED, u64 *htlc_minimum_msat UNNEEDED, u32 *fee_base_msat UNNEEDED, u32 *fee_proportional_millionths UNNEEDED) { fprintf(stderr, "fromwire_channel_update called!\n"); abort(); } -/* Generated stub for fromwire_ipaddr */ -bool fromwire_ipaddr(const u8 **cursor UNNEEDED, size_t *max UNNEEDED, struct ipaddr *addr UNNEEDED) -{ fprintf(stderr, "fromwire_ipaddr called!\n"); abort(); } /* Generated stub for fromwire_node_announcement */ bool fromwire_node_announcement(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, size_t *plen UNNEEDED, secp256k1_ecdsa_signature *signature UNNEEDED, u8 **features UNNEEDED, u32 *timestamp UNNEEDED, struct pubkey *node_id UNNEEDED, u8 rgb_color[3] UNNEEDED, u8 alias[32] UNNEEDED, u8 **addresses UNNEEDED) { fprintf(stderr, "fromwire_node_announcement called!\n"); abort(); } /* Generated stub for fromwire_u8 */ u8 fromwire_u8(const u8 **cursor UNNEEDED, size_t *max UNNEEDED) { fprintf(stderr, "fromwire_u8 called!\n"); abort(); } +/* Generated stub for fromwire_wireaddr */ +bool fromwire_wireaddr(const u8 **cursor UNNEEDED, size_t *max UNNEEDED, struct wireaddr *addr UNNEEDED) +{ fprintf(stderr, "fromwire_wireaddr called!\n"); abort(); } /* Generated stub for queue_broadcast */ void queue_broadcast(struct broadcast_state *bstate UNNEEDED, const int type UNNEEDED, diff --git a/gossipd/test/run-find_route.c b/gossipd/test/run-find_route.c index b286e78a9..236f3e8e2 100644 --- a/gossipd/test/run-find_route.c +++ b/gossipd/test/run-find_route.c @@ -18,15 +18,15 @@ bool fromwire_channel_announcement(const tal_t *ctx UNNEEDED, const void *p UNNE /* Generated stub for fromwire_channel_update */ bool fromwire_channel_update(const void *p UNNEEDED, size_t *plen UNNEEDED, secp256k1_ecdsa_signature *signature UNNEEDED, struct sha256_double *chain_hash UNNEEDED, struct short_channel_id *short_channel_id UNNEEDED, u32 *timestamp UNNEEDED, u16 *flags UNNEEDED, u16 *cltv_expiry_delta UNNEEDED, u64 *htlc_minimum_msat UNNEEDED, u32 *fee_base_msat UNNEEDED, u32 *fee_proportional_millionths UNNEEDED) { fprintf(stderr, "fromwire_channel_update called!\n"); abort(); } -/* Generated stub for fromwire_ipaddr */ -bool fromwire_ipaddr(const u8 **cursor UNNEEDED, size_t *max UNNEEDED, struct ipaddr *addr UNNEEDED) -{ fprintf(stderr, "fromwire_ipaddr called!\n"); abort(); } /* Generated stub for fromwire_node_announcement */ bool fromwire_node_announcement(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, size_t *plen UNNEEDED, secp256k1_ecdsa_signature *signature UNNEEDED, u8 **features UNNEEDED, u32 *timestamp UNNEEDED, struct pubkey *node_id UNNEEDED, u8 rgb_color[3] UNNEEDED, u8 alias[32] UNNEEDED, u8 **addresses UNNEEDED) { fprintf(stderr, "fromwire_node_announcement called!\n"); abort(); } /* Generated stub for fromwire_u8 */ u8 fromwire_u8(const u8 **cursor UNNEEDED, size_t *max UNNEEDED) { fprintf(stderr, "fromwire_u8 called!\n"); abort(); } +/* Generated stub for fromwire_wireaddr */ +bool fromwire_wireaddr(const u8 **cursor UNNEEDED, size_t *max UNNEEDED, struct wireaddr *addr UNNEEDED) +{ fprintf(stderr, "fromwire_wireaddr called!\n"); abort(); } /* Generated stub for queue_broadcast */ void queue_broadcast(struct broadcast_state *bstate UNNEEDED, const int type UNNEEDED, diff --git a/gossipd/test/run-initiator-success.c b/gossipd/test/run-initiator-success.c index 8f87df896..05367f33e 100644 --- a/gossipd/test/run-initiator-success.c +++ b/gossipd/test/run-initiator-success.c @@ -176,7 +176,7 @@ static struct io_plan *test_read(struct io_conn *conn, static struct io_plan *success(struct io_conn *conn, const struct pubkey *them, - const struct ipaddr *addr, + const struct wireaddr *addr, const struct crypto_state *cs, void *ctx) { @@ -200,7 +200,7 @@ bool hsm_do_ecdh(struct secret *ss, const struct pubkey *point) int main(void) { tal_t *ctx = tal_tmpctx(NULL); - struct ipaddr dummy; + struct wireaddr dummy; trc = tal_tmpctx(ctx); diff --git a/gossipd/test/run-responder-success.c b/gossipd/test/run-responder-success.c index ab3799d98..d23e5c3bc 100644 --- a/gossipd/test/run-responder-success.c +++ b/gossipd/test/run-responder-success.c @@ -176,7 +176,7 @@ static struct io_plan *test_read(struct io_conn *conn, static struct io_plan *success(struct io_conn *conn, const struct pubkey *them, - const struct ipaddr *addr, + const struct wireaddr *addr, const struct crypto_state *cs, void *ctx) { @@ -198,7 +198,7 @@ bool hsm_do_ecdh(struct secret *ss, const struct pubkey *point) int main(void) { tal_t *ctx = tal_tmpctx(NULL); - struct ipaddr dummy; + struct wireaddr dummy; trc = tal_tmpctx(ctx); diff --git a/lightningd/Makefile b/lightningd/Makefile index 42a844247..061c9233f 100644 --- a/lightningd/Makefile +++ b/lightningd/Makefile @@ -35,6 +35,7 @@ LIGHTNINGD_COMMON_OBJS := \ common/utxo.o \ common/version.o \ common/wire_error.o \ + common/wireaddr.o \ common/withdraw_tx.o LIGHTNINGD_SRC := \ diff --git a/lightningd/gossip_control.c b/lightningd/gossip_control.c index 91efb8593..6de52a94b 100644 --- a/lightningd/gossip_control.c +++ b/lightningd/gossip_control.c @@ -24,7 +24,7 @@ static void peer_nongossip(struct subd *gossip, const u8 *msg, { struct pubkey id; struct crypto_state cs; - struct ipaddr addr; + struct wireaddr addr; u8 *gfeatures, *lfeatures, *in_pkt; if (!fromwire_gossip_peer_nongossip(msg, msg, NULL, diff --git a/lightningd/gossip_msg.c b/lightningd/gossip_msg.c index 4d95ca8dd..6ad59863a 100644 --- a/lightningd/gossip_msg.c +++ b/lightningd/gossip_msg.c @@ -1,3 +1,4 @@ +#include #include #include @@ -7,10 +8,10 @@ void fromwire_gossip_getnodes_entry(const tal_t *ctx, const u8 **pptr, size_t *m fromwire_pubkey(pptr, max, &entry->nodeid); numaddresses = fromwire_u8(pptr, max); - entry->addresses = tal_arr(ctx, struct ipaddr, numaddresses); + entry->addresses = tal_arr(ctx, struct wireaddr, numaddresses); for (i=0; iaddresses)) { + if (!fromwire_wireaddr(pptr, max, entry->addresses)) { fromwire_fail(pptr, max); return; } @@ -23,7 +24,7 @@ void towire_gossip_getnodes_entry(u8 **pptr, const struct gossip_getnodes_entry towire_u8(pptr, numaddresses); for (i=0; iaddresses[i]); + towire_wireaddr(pptr, &entry->addresses[i]); } } diff --git a/lightningd/gossip_msg.h b/lightningd/gossip_msg.h index 652303423..d594f444a 100644 --- a/lightningd/gossip_msg.h +++ b/lightningd/gossip_msg.h @@ -6,7 +6,7 @@ struct gossip_getnodes_entry { struct pubkey nodeid; - struct ipaddr *addresses; + struct wireaddr *addresses; }; struct gossip_getchannels_entry { diff --git a/lightningd/jsonrpc.c b/lightningd/jsonrpc.c index 10396c5d4..318814b35 100644 --- a/lightningd/jsonrpc.c +++ b/lightningd/jsonrpc.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -372,7 +373,7 @@ void json_add_short_channel_id(struct json_result *response, } void json_add_address(struct json_result *response, const char *fieldname, - const struct ipaddr *addr) + const struct wireaddr *addr) { json_object_start(response, fieldname); char *addrstr = tal_arr(response, char, INET6_ADDRSTRLEN); diff --git a/lightningd/jsonrpc.h b/lightningd/jsonrpc.h index 22507d4be..3627a397f 100644 --- a/lightningd/jsonrpc.h +++ b/lightningd/jsonrpc.h @@ -5,6 +5,8 @@ #include #include +struct wireaddr; + /* Context for a command (from JSON, but might outlive the connection!) * You can allocate off this for temporary objects. */ struct command { @@ -70,7 +72,7 @@ void json_add_short_channel_id(struct json_result *response, /* JSON serialize a network address for a node */ void json_add_address(struct json_result *response, const char *fieldname, - const struct ipaddr *addr); + const struct wireaddr *addr); /* For initialization */ diff --git a/lightningd/lightningd.c b/lightningd/lightningd.c index 8cb5af3e3..3a3e1336e 100644 --- a/lightningd/lightningd.c +++ b/lightningd/lightningd.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -79,7 +80,7 @@ static struct lightningd *new_lightningd(const tal_t *ctx, ld->rgb = NULL; list_head_init(&ld->pay_commands); list_head_init(&ld->connects); - ld->wireaddrs = tal_arr(ld, struct ipaddr, 0); + ld->wireaddrs = tal_arr(ld, struct wireaddr, 0); ld->portnum = DEFAULT_PORT; timers_init(&ld->timers, time_mono()); ld->topology = new_topology(ld, ld->log); diff --git a/lightningd/lightningd.h b/lightningd/lightningd.h index 89c4b5408..7b1af26ac 100644 --- a/lightningd/lightningd.h +++ b/lightningd/lightningd.h @@ -95,7 +95,7 @@ struct lightningd { u16 portnum; /* Addresses to announce to the network (tal_count()) */ - struct ipaddr *wireaddrs; + struct wireaddr *wireaddrs; /* Bearer of all my secrets. */ int hsm_fd; diff --git a/lightningd/netaddress.c b/lightningd/netaddress.c index b4328b1b1..8b04012de 100644 --- a/lightningd/netaddress.c +++ b/lightningd/netaddress.c @@ -1,4 +1,6 @@ +#include #include +#include #include #include #include @@ -20,28 +22,28 @@ /* The common IPv4-in-IPv6 prefix */ static const unsigned char pchIPv4[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff }; -static bool IsRFC6145(const struct ipaddr *addr) +static bool IsRFC6145(const struct wireaddr *addr) { static const unsigned char pchRFC6145[] = {0,0,0,0,0,0,0,0,0xFF,0xFF,0,0}; return addr->type == ADDR_TYPE_IPV6 && memcmp(addr->addr, pchRFC6145, sizeof(pchRFC6145)) == 0; } -static bool IsRFC6052(const struct ipaddr *addr) +static bool IsRFC6052(const struct wireaddr *addr) { static const unsigned char pchRFC6052[] = {0,0x64,0xFF,0x9B,0,0,0,0,0,0,0,0}; return addr->type == ADDR_TYPE_IPV6 && memcmp(addr->addr, pchRFC6052, sizeof(pchRFC6052)) == 0; } -static bool IsRFC3964(const struct ipaddr *addr) +static bool IsRFC3964(const struct wireaddr *addr) { return addr->type == ADDR_TYPE_IPV6 && addr->addr[0] == 0x20 && addr->addr[1] == 0x02; } /* Return offset of IPv4 address, or 0 == not an IPv4 */ -static size_t IPv4In6(const struct ipaddr *addr) +static size_t IPv4In6(const struct wireaddr *addr) { if (addr->type != ADDR_TYPE_IPV6) return 0; @@ -57,17 +59,17 @@ static size_t IPv4In6(const struct ipaddr *addr) } /* Is this an IPv4 address, or an IPv6-wrapped IPv4 */ -static bool IsIPv4(const struct ipaddr *addr) +static bool IsIPv4(const struct wireaddr *addr) { return addr->type == ADDR_TYPE_IPV4 || IPv4In6(addr) != 0; } -static bool IsIPv6(const struct ipaddr *addr) +static bool IsIPv6(const struct wireaddr *addr) { return addr->type == ADDR_TYPE_IPV6 && IPv4In6(addr) == 0; } -static bool RawEq(const struct ipaddr *addr, const void *cmp, size_t len) +static bool RawEq(const struct wireaddr *addr, const void *cmp, size_t len) { size_t off = IPv4In6(addr); @@ -76,14 +78,14 @@ static bool RawEq(const struct ipaddr *addr, const void *cmp, size_t len) } /* The bitcoin code packs addresses backwards, so we map it here. */ -static unsigned int GetByte(const struct ipaddr *addr, int n) +static unsigned int GetByte(const struct wireaddr *addr, int n) { size_t off = IPv4In6(addr); assert(off + n < addr->addrlen); return addr->addr[addr->addrlen - 1 - off - n]; } -static bool IsRFC1918(const struct ipaddr *addr) +static bool IsRFC1918(const struct wireaddr *addr) { return IsIPv4(addr) && ( GetByte(addr, 3) == 10 || @@ -91,56 +93,56 @@ static bool IsRFC1918(const struct ipaddr *addr) (GetByte(addr, 3) == 172 && (GetByte(addr, 2) >= 16 && GetByte(addr, 2) <= 31))); } -static bool IsRFC2544(const struct ipaddr *addr) +static bool IsRFC2544(const struct wireaddr *addr) { return IsIPv4(addr) && GetByte(addr, 3) == 198 && (GetByte(addr, 2) == 18 || GetByte(addr, 2) == 19); } -static bool IsRFC3927(const struct ipaddr *addr) +static bool IsRFC3927(const struct wireaddr *addr) { return IsIPv4(addr) && (GetByte(addr, 3) == 169 && GetByte(addr, 2) == 254); } -static bool IsRFC6598(const struct ipaddr *addr) +static bool IsRFC6598(const struct wireaddr *addr) { return IsIPv4(addr) && GetByte(addr, 3) == 100 && GetByte(addr, 2) >= 64 && GetByte(addr, 2) <= 127; } -static bool IsRFC5737(const struct ipaddr *addr) +static bool IsRFC5737(const struct wireaddr *addr) { return IsIPv4(addr) && ((GetByte(addr, 3) == 192 && GetByte(addr, 2) == 0 && GetByte(addr, 1) == 2) || (GetByte(addr, 3) == 198 && GetByte(addr, 2) == 51 && GetByte(addr, 1) == 100) || (GetByte(addr, 3) == 203 && GetByte(addr, 2) == 0 && GetByte(addr, 1) == 113)); } -static bool IsRFC3849(const struct ipaddr *addr) +static bool IsRFC3849(const struct wireaddr *addr) { return IsIPv6(addr) && GetByte(addr, 15) == 0x20 && GetByte(addr, 14) == 0x01 && GetByte(addr, 13) == 0x0D && GetByte(addr, 12) == 0xB8; } -static bool IsRFC4862(const struct ipaddr *addr) +static bool IsRFC4862(const struct wireaddr *addr) { static const unsigned char pchRFC4862[] = {0xFE,0x80,0,0,0,0,0,0}; return IsIPv6(addr) && RawEq(addr, pchRFC4862, sizeof(pchRFC4862)); } -static bool IsRFC4193(const struct ipaddr *addr) +static bool IsRFC4193(const struct wireaddr *addr) { return IsIPv6(addr) && ((GetByte(addr, 15) & 0xFE) == 0xFC); } -static bool IsRFC4843(const struct ipaddr *addr) +static bool IsRFC4843(const struct wireaddr *addr) { return IsIPv6(addr) && (GetByte(addr, 15) == 0x20 && GetByte(addr, 14) == 0x01 && GetByte(addr, 13) == 0x00 && (GetByte(addr, 12) & 0xF0) == 0x10); } -static bool IsTor(const struct ipaddr *addr) +static bool IsTor(const struct wireaddr *addr) { /* FIXME */ return false; } -static bool IsLocal(const struct ipaddr *addr) +static bool IsLocal(const struct wireaddr *addr) { // IPv4 loopback if (IsIPv4(addr) && (GetByte(addr, 3) == 127 || GetByte(addr, 3) == 0)) @@ -154,12 +156,12 @@ static bool IsLocal(const struct ipaddr *addr) return false; } -static bool IsInternal(const struct ipaddr *addr) +static bool IsInternal(const struct wireaddr *addr) { return addr->type == ADDR_TYPE_PADDING; } -static bool IsValid(const struct ipaddr *addr) +static bool IsValid(const struct wireaddr *addr) { // unspecified IPv6 address (::/128) unsigned char ipNone6[16] = {}; @@ -189,7 +191,7 @@ static bool IsValid(const struct ipaddr *addr) return true; } -static bool IsRoutable(const struct ipaddr *addr) +static bool IsRoutable(const struct wireaddr *addr) { return IsValid(addr) && !(IsRFC1918(addr) || IsRFC2544(addr) || IsRFC3927(addr) || IsRFC4862(addr) || IsRFC6598(addr) || IsRFC5737(addr) || (IsRFC4193(addr) && !IsTor(addr)) || IsRFC4843(addr) || IsLocal(addr) || IsInternal(addr)); } @@ -216,8 +218,8 @@ static bool get_local_sockname(int af, void *saddr, socklen_t saddrlen) return true; } -/* Return an ipaddr without port filled in */ -static bool guess_one_address(struct ipaddr *addr, u16 portnum, +/* Return an wireaddr without port filled in */ +static bool guess_one_address(struct wireaddr *addr, u16 portnum, enum wire_addr_type type) { addr->type = type; @@ -273,3 +275,31 @@ void guess_addresses(struct lightningd *ld) if (!guess_one_address(&ld->wireaddrs[n], ld->portnum, ADDR_TYPE_IPV6)) tal_resize(&ld->wireaddrs, n); } + +bool parse_wireaddr(const char *arg, struct wireaddr *addr, u16 port) +{ + struct in6_addr v6; + struct in_addr v4; + + /* FIXME: change arg to addr[:port] and use getaddrinfo? */ + if (streq(arg, "localhost")) + arg = "127.0.0.1"; + else if (streq(arg, "ip6-localhost")) + arg = "::1"; + + memset(&addr->addr, 0, sizeof(addr->addr)); + if (inet_pton(AF_INET, arg, &v4) == 1) { + addr->type = ADDR_TYPE_IPV4; + addr->addrlen = 4; + addr->port = port; + memcpy(&addr->addr, &v4, addr->addrlen); + return true; + } else if (inet_pton(AF_INET6, arg, &v6) == 1) { + addr->type = ADDR_TYPE_IPV6; + addr->addrlen = 16; + addr->port = port; + memcpy(&addr->addr, &v6, addr->addrlen); + return true; + } + return false; +} diff --git a/lightningd/netaddress.h b/lightningd/netaddress.h index 7af7f779d..17b70e799 100644 --- a/lightningd/netaddress.h +++ b/lightningd/netaddress.h @@ -1,9 +1,12 @@ #ifndef LIGHTNING_LIGHTNINGD_NETADDRESS_H #define LIGHTNING_LIGHTNINGD_NETADDRESS_H #include "config.h" +#include struct lightningd; void guess_addresses(struct lightningd *ld); +bool parse_wireaddr(const char *arg, struct wireaddr *addr, u16 port); + #endif /* LIGHTNING_LIGHTNINGD_NETADDRESS_H */ diff --git a/lightningd/options.c b/lightningd/options.c index 248a340ad..d3fa48a16 100644 --- a/lightningd/options.c +++ b/lightningd/options.c @@ -1,4 +1,3 @@ -#include #include #include #include @@ -9,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -118,42 +118,13 @@ static char *opt_set_s32(const char *arg, s32 *u) return NULL; } -/* FIXME: Rename ipaddr and hoist up */ -bool parse_ipaddr(const char *arg, struct ipaddr *addr, u16 port) -{ - struct in6_addr v6; - struct in_addr v4; - - /* FIXME: change arg to addr[:port] and use getaddrinfo? */ - if (streq(arg, "localhost")) - arg = "127.0.0.1"; - else if (streq(arg, "ip6-localhost")) - arg = "::1"; - - memset(&addr->addr, 0, sizeof(addr->addr)); - if (inet_pton(AF_INET, arg, &v4) == 1) { - addr->type = ADDR_TYPE_IPV4; - addr->addrlen = 4; - addr->port = port; - memcpy(&addr->addr, &v4, addr->addrlen); - return true; - } else if (inet_pton(AF_INET6, arg, &v6) == 1) { - addr->type = ADDR_TYPE_IPV6; - addr->addrlen = 16; - addr->port = port; - memcpy(&addr->addr, &v6, addr->addrlen); - return true; - } - return false; -} - static char *opt_add_ipaddr(const char *arg, struct lightningd *ld) { size_t n = tal_count(ld->wireaddrs); tal_resize(&ld->wireaddrs, n+1); - if (parse_ipaddr(arg, &ld->wireaddrs[n], ld->portnum)) + if (parse_wireaddr(arg, &ld->wireaddrs[n], ld->portnum)) return NULL; return tal_fmt(NULL, "Unable to parse IP address '%s'", arg); diff --git a/lightningd/options.h b/lightningd/options.h index 2519a8c53..8794c7e87 100644 --- a/lightningd/options.h +++ b/lightningd/options.h @@ -13,8 +13,6 @@ void register_opts(struct lightningd *ld); */ bool handle_opts(struct lightningd *ld, int argc, char *argv[]); -bool parse_ipaddr(const char *arg, struct ipaddr *addr, u16 port); - /* Derive default color and alias from the pubkey. */ void setup_color_and_alias(struct lightningd *ld); #endif /* LIGHTNING_LIGHTNINGD_OPTIONS_H */ diff --git a/lightningd/peer_control.c b/lightningd/peer_control.c index 2d0458c31..e90fd5d2e 100644 --- a/lightningd/peer_control.c +++ b/lightningd/peer_control.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -57,7 +58,7 @@ struct connect { struct funding_channel; static void peer_offer_channel(struct lightningd *ld, struct funding_channel *fc, - const struct ipaddr *addr, + const struct wireaddr *addr, const struct crypto_state *cs, const u8 *gfeatures, const u8 *lfeatures, int peer_fd, int gossip_fd); @@ -72,7 +73,7 @@ static void peer_start_closingd(struct peer *peer, bool reconnected); static void peer_accept_channel(struct lightningd *ld, const struct pubkey *peer_id, - const struct ipaddr *addr, + const struct wireaddr *addr, const struct crypto_state *cs, const u8 *gfeatures, const u8 *lfeatures, int peer_fd, int gossip_fd, @@ -308,7 +309,7 @@ static void connect_failed(struct lightningd *ld, const struct pubkey *id, static struct peer *new_peer(struct lightningd *ld, const struct pubkey *id, - const struct ipaddr *addr, + const struct wireaddr *addr, const u8 *gfeatures, const u8 *lfeatures, int peer_fd) { @@ -505,7 +506,7 @@ void peer_connected(struct lightningd *ld, const u8 *msg, u8 *gfeatures, *lfeatures; u8 *error; struct peer *peer; - struct ipaddr addr; + struct wireaddr addr; if (!fromwire_gossip_peer_connected(msg, msg, NULL, &id, &addr, &cs, @@ -611,7 +612,7 @@ send_error: void peer_sent_nongossip(struct lightningd *ld, const struct pubkey *id, - const struct ipaddr *addr, + const struct wireaddr *addr, const struct crypto_state *cs, const u8 *gfeatures, const u8 *lfeatures, @@ -709,7 +710,7 @@ static void json_connect(struct command *cmd, jsmntok_t *hosttok, *idtok; struct pubkey id; const char *name, *port, *colon; - struct ipaddr addr; + struct wireaddr addr; u8 *msg; if (!json_get_params(buffer, params, @@ -741,7 +742,7 @@ static void json_connect(struct command *cmd, port = tal_strdup(cmd, stringify(DEFAULT_PORT)); } addr.port = atoi(port); - if (!parse_ipaddr(name, &addr, addr.port) || !addr.port) + if (!parse_wireaddr(name, &addr, addr.port) || !addr.port) command_fail(cmd, "host %s:%s not valid", name, port); /* Tell it about the address. */ @@ -785,7 +786,7 @@ static void log_to_json(unsigned int skipped, json_add_string(info->response, NULL, log); } -static const char *ipaddr_name(const tal_t *ctx, const struct ipaddr *a) +static const char *wireaddr_name(const tal_t *ctx, const struct wireaddr *a) { char name[INET6_ADDRSTRLEN]; int af; @@ -838,7 +839,7 @@ static void json_getpeers(struct command *cmd, json_object_start(response, NULL); json_add_string(response, "state", peer_state_name(p->state)); json_add_string(response, "netaddr", - ipaddr_name(response, &p->addr)); + wireaddr_name(response, &p->addr)); json_add_pubkey(response, "peerid", &p->id); json_add_bool(response, "connected", p->owner != NULL); if (p->owner) @@ -1478,7 +1479,7 @@ static u8 *create_node_announcement(const tal_t *ctx, struct lightningd *ld, memset(sig, 0, sizeof(*sig)); } for (i = 0; i < tal_count(ld->wireaddrs); i++) - towire_ipaddr(&addresses, ld->wireaddrs+i); + towire_wireaddr(&addresses, ld->wireaddrs+i); announcement = towire_node_announcement(ctx, sig, features, timestamp, @@ -2231,7 +2232,7 @@ static void opening_fundee_finished(struct subd *opening, /* Peer has spontaneously exited from gossip due to open msg */ static void peer_accept_channel(struct lightningd *ld, const struct pubkey *peer_id, - const struct ipaddr *addr, + const struct wireaddr *addr, const struct crypto_state *cs, const u8 *gfeatures, const u8 *lfeatures, int peer_fd, int gossip_fd, @@ -2299,7 +2300,7 @@ static void peer_accept_channel(struct lightningd *ld, static void peer_offer_channel(struct lightningd *ld, struct funding_channel *fc, - const struct ipaddr *addr, + const struct wireaddr *addr, const struct crypto_state *cs, const u8 *gfeatures, const u8 *lfeatures, int peer_fd, int gossip_fd) @@ -2390,7 +2391,7 @@ static void gossip_peer_released(struct subd *gossip, struct lightningd *ld = gossip->ld; struct crypto_state cs; u8 *gfeatures, *lfeatures; - struct ipaddr addr; + struct wireaddr addr; /* We could have raced with peer doing something else. */ fc->peer = peer_by_id(ld, &fc->peerid); diff --git a/lightningd/peer_control.h b/lightningd/peer_control.h index 6eb00ae13..f22911657 100644 --- a/lightningd/peer_control.h +++ b/lightningd/peer_control.h @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -54,7 +55,7 @@ struct peer { u8 channel_flags; /* Where we connected to, or it connected from. */ - struct ipaddr addr; + struct wireaddr addr; /* Our channel config. */ struct channel_config our_config; @@ -167,7 +168,7 @@ void peer_connected(struct lightningd *ld, const u8 *msg, void peer_sent_nongossip(struct lightningd *ld, const struct pubkey *id, - const struct ipaddr *addr, + const struct wireaddr *addr, const struct crypto_state *cs, const u8 *gfeatures, const u8 *lfeatures, diff --git a/wire/fromwire.c b/wire/fromwire.c index f9e118c93..0925eb6bd 100644 --- a/wire/fromwire.c +++ b/wire/fromwire.c @@ -170,37 +170,6 @@ void fromwire_ripemd160(const u8 **cursor, size_t *max, struct ripemd160 *ripemd fromwire(cursor, max, ripemd, sizeof(*ripemd)); } -/* BOLT #7: - * - * The following `address descriptor` types are defined: - * - * * `0`: padding. data = none (length 0). - * * `1`: ipv4. data = `[4:ipv4_addr][2:port]` (length 6) - * * `2`: ipv6. data = `[16:ipv6_addr][2:port]` (length 18) - */ -/* FIXME: Tor addresses! */ - -/* Returns false if we didn't parse it, and *cursor == NULL if malformed. */ -bool fromwire_ipaddr(const u8 **cursor, size_t *max, struct ipaddr *addr) -{ - addr->type = fromwire_u8(cursor, max); - - switch (addr->type) { - case ADDR_TYPE_IPV4: - addr->addrlen = 4; - break; - case ADDR_TYPE_IPV6: - addr->addrlen = 16; - break; - default: - return false; - } - fromwire(cursor, max, addr->addr, addr->addrlen); - addr->port = fromwire_u16(cursor, max); - - return *cursor != NULL; -} - void fromwire_u8_array(const u8 **cursor, size_t *max, u8 *arr, size_t num) { fromwire(cursor, max, arr, num); diff --git a/wire/towire.c b/wire/towire.c index 62ddca0f1..872721698 100644 --- a/wire/towire.c +++ b/wire/towire.c @@ -115,13 +115,6 @@ void towire_ripemd160(u8 **pptr, const struct ripemd160 *ripemd) towire(pptr, ripemd, sizeof(*ripemd)); } -void towire_ipaddr(u8 **pptr, const struct ipaddr *addr) -{ - towire_u8(pptr, addr->type); - towire(pptr, addr->addr, addr->addrlen); - towire_u16(pptr, addr->port); -} - void towire_u8_array(u8 **pptr, const u8 *arr, size_t num) { towire(pptr, arr, num); diff --git a/wire/wire.h b/wire/wire.h index b75143854..7d2c49f20 100644 --- a/wire/wire.h +++ b/wire/wire.h @@ -14,25 +14,6 @@ struct channel_id { u8 id[32]; }; -/* Address types as defined in the lightning specification. Does not - * match AF_INET and AF_INET6 so we just define our - * own. ADDR_TYPE_PADDING is also used to signal in the config whether - * an address is defined at all. */ -enum wire_addr_type { - ADDR_TYPE_PADDING = 0, - ADDR_TYPE_IPV4 = 1, - ADDR_TYPE_IPV6 = 2, -}; - -/* FIXME(cdecker) Extend this once we have defined how TOR addresses - * should look like */ -struct ipaddr { - enum wire_addr_type type; - u8 addrlen; - u8 addr[16]; - u16 port; -}; - struct preimage; struct ripemd160; @@ -56,7 +37,6 @@ void towire_sha256(u8 **pptr, const struct sha256 *sha256); void towire_sha256_double(u8 **pptr, const struct sha256_double *sha256d); void towire_preimage(u8 **pptr, const struct preimage *preimage); void towire_ripemd160(u8 **pptr, const struct ripemd160 *ripemd); -void towire_ipaddr(u8 **pptr, const struct ipaddr *addr); void towire_u8(u8 **pptr, u8 v); void towire_u16(u8 **pptr, u16 v); void towire_u32(u8 **pptr, u32 v); @@ -86,7 +66,6 @@ void fromwire_sha256_double(const u8 **cursor, size_t *max, struct sha256_double *sha256d); void fromwire_preimage(const u8 **cursor, size_t *max, struct preimage *preimage); void fromwire_ripemd160(const u8 **cursor, size_t *max, struct ripemd160 *ripemd); -bool fromwire_ipaddr(const u8 **cursor, size_t *max, struct ipaddr *addr); void fromwire_pad(const u8 **cursor, size_t *max, size_t num); void fromwire_u8_array(const u8 **cursor, size_t *max, u8 *arr, size_t num);