Skip to content

Commit ee9e300

Browse files
rustyrussellcdecker
authored andcommitted
gossip: fix address descriptor handling.
1. The code to skip over padding didn't take into account max. 2. It also didn't use symbolic names. 3. We are not supposed to fail on unknown addresses, just stop parsing. 4. We don't use the read_ip/write_ip code, so get rid of it. Signed-off-by: Rusty Russell <[email protected]>
1 parent 6933db0 commit ee9e300

File tree

7 files changed

+50
-129
lines changed

7 files changed

+50
-129
lines changed

gossipd/routing.c

+20-111
Original file line numberDiff line numberDiff line change
@@ -427,109 +427,6 @@ static bool add_channel_direction(struct routing_state *rstate,
427427
return true;
428428
}
429429

430-
/* BOLT #7:
431-
*
432-
* The following `address descriptor` types are defined:
433-
*
434-
* * `0`: padding. data = none (length 0).
435-
* * `1`: ipv4. data = `[4:ipv4_addr][2:port]` (length 6)
436-
* * `2`: ipv6. data = `[16:ipv6_addr][2:port]` (length 18)
437-
*/
438-
439-
/* FIXME: Don't just take first one, depends whether we have IPv6 ourselves */
440-
/* Returns false iff it was malformed */
441-
bool read_ip(const tal_t *ctx, const u8 *addresses, char **hostname,
442-
int *port)
443-
{
444-
size_t len = tal_count(addresses);
445-
const u8 *p = addresses;
446-
char tempaddr[INET6_ADDRSTRLEN];
447-
be16 portnum;
448-
449-
*hostname = NULL;
450-
while (len) {
451-
u8 type = *p;
452-
p++;
453-
len--;
454-
455-
switch (type) {
456-
case 0:
457-
break;
458-
case 1:
459-
/* BOLT #7:
460-
*
461-
* The receiving node SHOULD fail the connection if
462-
* `addrlen` is insufficient to hold the address
463-
* descriptors of the known types.
464-
*/
465-
if (len < 6)
466-
return false;
467-
inet_ntop(AF_INET, p, tempaddr, sizeof(tempaddr));
468-
memcpy(&portnum, p + 4, sizeof(portnum));
469-
*hostname = tal_strdup(ctx, tempaddr);
470-
*port = be16_to_cpu(portnum);
471-
return true;
472-
case 2:
473-
if (len < 18)
474-
return false;
475-
inet_ntop(AF_INET6, p, tempaddr, sizeof(tempaddr));
476-
memcpy(&portnum, p + 16, sizeof(portnum));
477-
*hostname = tal_strdup(ctx, tempaddr);
478-
*port = be16_to_cpu(portnum);
479-
return true;
480-
default:
481-
/* BOLT #7:
482-
*
483-
* The receiving node SHOULD ignore the first `address
484-
* descriptor` which does not match the types defined
485-
* above.
486-
*/
487-
return true;
488-
}
489-
}
490-
491-
/* Not a fatal error. */
492-
return true;
493-
}
494-
495-
/* BOLT #7:
496-
*
497-
* The creating node SHOULD fill `addresses` with an address descriptor for
498-
* each public network address which expects incoming connections, and MUST
499-
* set `addrlen` to the number of bytes in `addresses`. Non-zero typed
500-
* address descriptors MUST be placed in ascending order; any number of
501-
* zero-typed address descriptors MAY be placed anywhere, but SHOULD only be
502-
* used for aligning fields following `addresses`.
503-
*
504-
* The creating node MUST NOT create a type 1 or type 2 address descriptor
505-
* with `port` equal to zero, and SHOULD ensure `ipv4_addr` and `ipv6_addr`
506-
* are routable addresses. The creating node MUST NOT include more than one
507-
* `address descriptor` of the same type.
508-
*/
509-
/* FIXME: handle case where we have both ipv6 and ipv4 addresses! */
510-
u8 *write_ip(const tal_t *ctx, const char *srcip, int port)
511-
{
512-
u8 *address;
513-
be16 portnum = cpu_to_be16(port);
514-
515-
if (!port)
516-
return tal_arr(ctx, u8, 0);
517-
518-
if (!strchr(srcip, ':')) {
519-
address = tal_arr(ctx, u8, 7);
520-
address[0] = 1;
521-
inet_pton(AF_INET, srcip, address+1);
522-
memcpy(address + 5, &portnum, sizeof(portnum));
523-
return address;
524-
} else {
525-
address = tal_arr(ctx, u8, 18);
526-
address[0] = 2;
527-
inet_pton(AF_INET6, srcip, address+1);
528-
memcpy(address + 17, &portnum, sizeof(portnum));
529-
return address;
530-
}
531-
}
532-
533430
/* Verify the signature of a channel_update message */
534431
static bool check_channel_update(const struct pubkey *node_key,
535432
const secp256k1_ecdsa_signature *node_sig,
@@ -731,20 +628,32 @@ void handle_channel_update(struct routing_state *rstate, const u8 *update, size_
731628
tal_free(tmpctx);
732629
}
733630

734-
static struct ipaddr *read_addresses(const tal_t *ctx, u8 *ser)
631+
static struct ipaddr *read_addresses(const tal_t *ctx, const u8 *ser)
735632
{
736633
const u8 *cursor = ser;
737634
size_t max = tal_len(ser);
738635
struct ipaddr *ipaddrs = tal_arr(ctx, struct ipaddr, 0);
739636
int numaddrs = 0;
740-
while (cursor < ser + max) {
741-
numaddrs++;
742-
tal_resize(&ipaddrs, numaddrs);
743-
fromwire_ipaddr(&cursor, &max, &ipaddrs[numaddrs-1]);
744-
if (cursor == NULL) {
745-
/* Parsing address failed */
746-
return tal_free(ipaddrs);
637+
while (cursor && cursor < ser + max) {
638+
struct ipaddr ipaddr;
639+
640+
/* BOLT #7:
641+
*
642+
* The receiving node SHOULD ignore the first `address
643+
* descriptor` which does not match the types defined
644+
* above.
645+
*/
646+
if (!fromwire_ipaddr(&cursor, &max, &ipaddr)) {
647+
if (!cursor)
648+
/* Parsing address failed */
649+
return tal_free(ipaddrs);
650+
/* Unknown type, stop there. */
651+
break;
747652
}
653+
654+
tal_resize(&ipaddrs, numaddrs+1);
655+
ipaddrs[numaddrs] = ipaddr;
656+
numaddrs++;
748657
}
749658
return ipaddrs;
750659
}

gossipd/routing.h

-3
Original file line numberDiff line numberDiff line change
@@ -115,9 +115,6 @@ struct node_connection *get_connection_by_scid(const struct routing_state *rstat
115115
const struct short_channel_id *schanid,
116116
const u8 direction);
117117

118-
bool read_ip(const tal_t *ctx, const u8 *addresses, char **hostname, int *port);
119-
u8 *write_ip(const tal_t *ctx, const char *srcip, int port);
120-
121118
/* Handlers for incoming messages */
122119
void handle_channel_announcement(struct routing_state *rstate, const u8 *announce, size_t len);
123120
void handle_channel_update(struct routing_state *rstate, const u8 *update, size_t len);

gossipd/test/run-find_route-specific.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ bool fromwire_channel_announcement(const tal_t *ctx UNNEEDED, const void *p UNNE
2626
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)
2727
{ fprintf(stderr, "fromwire_channel_update called!\n"); abort(); }
2828
/* Generated stub for fromwire_ipaddr */
29-
void fromwire_ipaddr(const u8 **cursor UNNEEDED, size_t *max UNNEEDED, struct ipaddr *addr UNNEEDED)
29+
bool fromwire_ipaddr(const u8 **cursor UNNEEDED, size_t *max UNNEEDED, struct ipaddr *addr UNNEEDED)
3030
{ fprintf(stderr, "fromwire_ipaddr called!\n"); abort(); }
3131
/* Generated stub for fromwire_node_announcement */
3232
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)

gossipd/test/run-find_route.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ bool fromwire_channel_announcement(const tal_t *ctx UNNEEDED, const void *p UNNE
1919
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)
2020
{ fprintf(stderr, "fromwire_channel_update called!\n"); abort(); }
2121
/* Generated stub for fromwire_ipaddr */
22-
void fromwire_ipaddr(const u8 **cursor UNNEEDED, size_t *max UNNEEDED, struct ipaddr *addr UNNEEDED)
22+
bool fromwire_ipaddr(const u8 **cursor UNNEEDED, size_t *max UNNEEDED, struct ipaddr *addr UNNEEDED)
2323
{ fprintf(stderr, "fromwire_ipaddr called!\n"); abort(); }
2424
/* Generated stub for fromwire_node_announcement */
2525
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)

lightningd/gossip_msg.c

+5-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,11 @@ void fromwire_gossip_getnodes_entry(const tal_t *ctx, const u8 **pptr, size_t *m
99

1010
entry->addresses = tal_arr(ctx, struct ipaddr, numaddresses);
1111
for (i=0; i<numaddresses; i++) {
12-
fromwire_ipaddr(pptr, max, entry->addresses);
12+
/* Gossipd doesn't hand us addresses we can't understand. */
13+
if (!fromwire_ipaddr(pptr, max, entry->addresses)) {
14+
fromwire_fail(pptr, max);
15+
return;
16+
}
1317
}
1418
}
1519
void towire_gossip_getnodes_entry(u8 **pptr, const struct gossip_getnodes_entry *entry)

wire/fromwire.c

+22-11
Original file line numberDiff line numberDiff line change
@@ -170,28 +170,39 @@ void fromwire_ripemd160(const u8 **cursor, size_t *max, struct ripemd160 *ripemd
170170
fromwire(cursor, max, ripemd, sizeof(*ripemd));
171171
}
172172

173-
void fromwire_ipaddr(const u8 **cursor, size_t *max, struct ipaddr *addr)
173+
/* BOLT #7:
174+
*
175+
* The following `address descriptor` types are defined:
176+
*
177+
* * `0`: padding. data = none (length 0).
178+
* * `1`: ipv4. data = `[4:ipv4_addr][2:port]` (length 6)
179+
* * `2`: ipv6. data = `[16:ipv6_addr][2:port]` (length 18)
180+
*/
181+
/* FIXME: Tor addresses! */
182+
183+
/* Returns false if we didn't parse it, and *cursor == NULL if malformed. */
184+
bool fromwire_ipaddr(const u8 **cursor, size_t *max, struct ipaddr *addr)
174185
{
175-
/* Skip any eventual padding */
176-
while (**cursor == 0) {
177-
(*cursor)++;
178-
}
186+
addr->type = fromwire_u8(cursor, max);
179187

180-
addr->type = **cursor;
181-
(*cursor)++;
182188
switch (addr->type) {
183-
case 1:
189+
case ADDR_TYPE_IPV4:
184190
addr->addrlen = 4;
185191
break;
186-
case 2:
192+
case ADDR_TYPE_IPV6:
187193
addr->addrlen = 16;
188194
break;
189195
default:
190-
fromwire_fail(cursor, max);
191-
return;
196+
return false;
192197
}
193198
fromwire(cursor, max, addr->addr, addr->addrlen);
194199
addr->port = fromwire_u16(cursor, max);
200+
201+
/* Skip any post-padding */
202+
while (*max && (*cursor)[0] == ADDR_TYPE_PADDING)
203+
fromwire_u8(cursor, max);
204+
205+
return *cursor != NULL;
195206
}
196207

197208
void fromwire_u8_array(const u8 **cursor, size_t *max, u8 *arr, size_t num)

wire/wire.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ void fromwire_sha256_double(const u8 **cursor, size_t *max,
8686
struct sha256_double *sha256d);
8787
void fromwire_preimage(const u8 **cursor, size_t *max, struct preimage *preimage);
8888
void fromwire_ripemd160(const u8 **cursor, size_t *max, struct ripemd160 *ripemd);
89-
void fromwire_ipaddr(const u8 **cursor, size_t *max, struct ipaddr *addr);
89+
bool fromwire_ipaddr(const u8 **cursor, size_t *max, struct ipaddr *addr);
9090
void fromwire_pad(const u8 **cursor, size_t *max, size_t num);
9191

9292
void fromwire_u8_array(const u8 **cursor, size_t *max, u8 *arr, size_t num);

0 commit comments

Comments
 (0)