From ed9668339d3134105e863e7345c08cca521b7819 Mon Sep 17 00:00:00 2001 From: Christian Decker Date: Mon, 8 May 2017 15:15:29 +0200 Subject: [PATCH] routing: Add command line option to specify external IP address We don't currently have a good way to determine our external IP address so let's at least give people an option to manually specify it. --- daemon/lightningd.h | 4 ++++ daemon/options.c | 33 +++++++++++++++++++++++++++++++++ wire/fromwire.c | 22 ++++++++++++++++++++-- wire/towire.c | 6 ++++-- wire/wire.h | 23 ++++++++++++++++++++--- 5 files changed, 81 insertions(+), 7 deletions(-) diff --git a/daemon/lightningd.h b/daemon/lightningd.h index ae6c826fd..354e236ed 100644 --- a/daemon/lightningd.h +++ b/daemon/lightningd.h @@ -7,6 +7,7 @@ #include #include #include +#include /* Various adjustable things. */ struct config { @@ -58,6 +59,9 @@ struct config { /* Whether to ignore database version. */ bool db_version_ignore; + + /* IPv4 or IPv6 address to announce to the network */ + struct ipaddr ipaddr; }; /* Here's where the global variables hide! */ diff --git a/daemon/options.c b/daemon/options.c index a141c7647..b6ed7f288 100644 --- a/daemon/options.c +++ b/daemon/options.c @@ -7,6 +7,7 @@ #include "daemon/options.h" #include "daemon/routing.h" #include "version.h" +#include #include #include #include @@ -20,6 +21,7 @@ #include #include #include +#include /* Tal wrappers for opt. */ static void *opt_allocfn(size_t size) @@ -109,6 +111,26 @@ static char *opt_set_s32(const char *arg, s32 *u) return NULL; } +static char *opt_set_ipaddr(const char *arg, struct ipaddr *addr) +{ + struct in6_addr v6; + struct in_addr v4; + char *err = NULL; + memset(&addr->addr, 0, sizeof(addr->addr)); + if (inet_pton(AF_INET, arg, &v4) == 1) { + addr->type = ADDR_TYPE_IPV4; + addr->addrlen = 4; + memcpy(&addr->addr, &v4, addr->addrlen); + } else if (inet_pton(AF_INET6, arg, &v6) == 1) { + addr->type = ADDR_TYPE_IPV6; + addr->addrlen = 16; + memcpy(&addr->addr, &v6, addr->addrlen); + } else { + err = tal_fmt(NULL, "Unable to parse IP address '%s'", arg); + } + return err; +} + static void opt_show_u64(char buf[OPT_SHOW_LEN], const u64 *u) { snprintf(buf, OPT_SHOW_LEN, "%"PRIu64, *u); @@ -205,6 +227,10 @@ static void config_register_opts(struct lightningd_state *dstate) opt_register_noarg("--ignore-dbversion", opt_set_bool, &dstate->config.db_version_ignore, "Continue despite invalid database version (DANGEROUS!)"); + + opt_register_arg("--ipaddr", opt_set_ipaddr, NULL, + &dstate->config.ipaddr, + "Set the IP address (v4 or v6) to announce to the network for incoming connections"); } static void dev_register_opts(struct lightningd_state *dstate) @@ -273,6 +299,9 @@ static const struct config testnet_config = { /* Don't ignore database version */ .db_version_ignore = false, + + /* Do not advertise any IP */ + .ipaddr.type = 0, }; /* aka. "Dude, where's my coins?" */ @@ -334,6 +363,9 @@ static const struct config mainnet_config = { /* Don't ignore database version */ .db_version_ignore = false, + + /* Do not advertise any IP */ + .ipaddr.type = 0, }; static void check_config(struct lightningd_state *dstate) @@ -488,6 +520,7 @@ bool handle_opts(struct lightningd_state *dstate, int argc, char *argv[]) /* Now look for config file */ opt_parse_from_config(dstate); + dstate->config.ipaddr.port = dstate->portnum; opt_parse(&argc, argv, opt_log_stderr_exit); if (argc != 1) errx(1, "no arguments accepted"); diff --git a/wire/fromwire.c b/wire/fromwire.c index 3ffd05d03..4dd16b9ca 100644 --- a/wire/fromwire.c +++ b/wire/fromwire.c @@ -165,9 +165,27 @@ void fromwire_preimage(const u8 **cursor, size_t *max, struct preimage *preimage fromwire(cursor, max, preimage, sizeof(*preimage)); } -void fromwire_ipv6(const u8 **cursor, size_t *max, struct ipv6 *ipv6) +void fromwire_ipaddr(const u8 **cursor, size_t *max, struct ipaddr *addr) { - fromwire(cursor, max, ipv6, sizeof(*ipv6)); + /* Skip any eventual padding */ + while (**cursor == 0) { + *cursor += 1; + } + + addr->type = **cursor; + switch (addr->type) { + case 1: + addr->addrlen = 4; + break; + case 2: + addr->addrlen = 16; + break; + default: + fail_pull(cursor, max); + return; + } + fromwire(cursor, max, addr->addr, addr->addrlen); + addr->port = fromwire_u16(cursor, max); } void fromwire_u8_array(const u8 **cursor, size_t *max, u8 *arr, size_t num) diff --git a/wire/towire.c b/wire/towire.c index 3f53e1f15..258e589af 100644 --- a/wire/towire.c +++ b/wire/towire.c @@ -109,9 +109,11 @@ void towire_preimage(u8 **pptr, const struct preimage *preimage) towire(pptr, preimage, sizeof(*preimage)); } -void towire_ipv6(u8 **pptr, const struct ipv6 *ipv6) +void towire_ipaddr(u8 **pptr, const struct ipaddr *addr) { - towire(pptr, ipv6, sizeof(*ipv6)); + 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) diff --git a/wire/wire.h b/wire/wire.h index 1aea3e09e..c17e7ba2a 100644 --- a/wire/wire.h +++ b/wire/wire.h @@ -17,9 +17,26 @@ struct short_channel_id { struct channel_id { u8 id[32]; }; -struct ipv6 { + +/* 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; void derive_channel_id(struct channel_id *channel_id, @@ -40,7 +57,7 @@ void towire_short_channel_id(u8 **pptr, 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_ipv6(u8 **pptr, const struct ipv6 *ipv6); +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); @@ -69,7 +86,7 @@ void fromwire_sha256(const u8 **cursor, size_t *max, struct sha256 *sha256); 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_ipv6(const u8 **cursor, size_t *max, struct ipv6 *ipv6); +void 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);