Browse Source

type_to_string: format wireaddr.

Good for printing, and removes some code from peer_control.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
ppa-0.6.1
Rusty Russell 7 years ago
parent
commit
a7d6326bef
  1. 1
      common/type_to_string.h
  2. 29
      common/wireaddr.c
  3. 37
      lightningd/netaddress.c
  4. 10
      lightningd/options.c
  5. 25
      lightningd/peer_control.c

1
common/type_to_string.h

@ -18,6 +18,7 @@ union printable_types {
const struct preimage *preimage;
const struct channel_state *channel_state;
const struct channel_oneside *channel_oneside;
const struct wireaddr *wireaddr;
const secp256k1_pubkey *secp256k1_pubkey;
const struct channel_id *channel_id;
const struct short_channel_id *short_channel_id;

29
common/wireaddr.c

@ -1,3 +1,7 @@
#include <arpa/inet.h>
#include <ccan/tal/str/str.h>
#include <common/type_to_string.h>
#include <common/utils.h>
#include <common/wireaddr.h>
#include <wire/wire.h>
@ -28,3 +32,28 @@ void towire_wireaddr(u8 **pptr, const struct wireaddr *addr)
towire(pptr, addr->addr, addr->addrlen);
towire_u16(pptr, addr->port);
}
static char *fmt_wireaddr(const tal_t *ctx, const struct wireaddr *a)
{
char addrstr[INET6_ADDRSTRLEN];
char *ret, *hex;
switch (a->type) {
case ADDR_TYPE_IPV4:
if (!inet_ntop(AF_INET, a->addr, addrstr, INET_ADDRSTRLEN))
return "Unprintable-ipv4-address";
return tal_fmt(ctx, "%s:%u", addrstr, a->port);
case ADDR_TYPE_IPV6:
if (!inet_ntop(AF_INET6, a->addr, addrstr, INET6_ADDRSTRLEN))
return "Unprintable-ipv6-address";
return tal_fmt(ctx, "%s:%u", addrstr, a->port);
case ADDR_TYPE_PADDING:
break;
}
hex = tal_hexstr(ctx, a->addr, a->addrlen);
ret = tal_fmt(ctx, "Unknown type %u %s:%u", a->type, hex, a->port);
tal_free(hex);
return ret;
}
REGISTER_TYPE_TO_STRING(wireaddr, fmt_wireaddr);

37
lightningd/netaddress.c

@ -1,7 +1,9 @@
#include <arpa/inet.h>
#include <assert.h>
#include <common/wireaddr.h>
#include <errno.h>
#include <lightningd/lightningd.h>
#include <lightningd/log.h>
#include <lightningd/netaddress.h>
#include <netinet/in.h>
#include <stdbool.h>
@ -198,18 +200,26 @@ static bool IsRoutable(const struct wireaddr *addr)
/* Trick I learned from Harald Welte: create UDP socket, connect() and
* then query address. */
static bool get_local_sockname(int af, void *saddr, socklen_t saddrlen)
static bool get_local_sockname(struct lightningd *ld,
int af, void *saddr, socklen_t saddrlen)
{
int fd = socket(af, SOCK_DGRAM, 0);
if (fd < 0)
if (fd < 0) {
log_debug(ld->log, "Failed to create %u socket: %s",
af, strerror(errno));
return false;
}
if (connect(fd, saddr, saddrlen) != 0) {
log_debug(ld->log, "Failed to connect %u socket: %s",
af, strerror(errno));
close(fd);
return false;
}
if (getsockname(fd, saddr, &saddrlen) != 0) {
log_debug(ld->log, "Failed to get %u socket name: %s",
af, strerror(errno));
close(fd);
return false;
}
@ -219,7 +229,8 @@ static bool get_local_sockname(int af, void *saddr, socklen_t saddrlen)
}
/* Return an wireaddr without port filled in */
static bool guess_one_address(struct wireaddr *addr, u16 portnum,
static bool guess_one_address(struct lightningd *ld,
struct wireaddr *addr, u16 portnum,
enum wire_addr_type type)
{
addr->type = type;
@ -232,7 +243,8 @@ static bool guess_one_address(struct wireaddr *addr, u16 portnum,
sin.sin_port = htons(53);
/* 8.8.8.8 */
sin.sin_addr.s_addr = 0x08080808;
if (!get_local_sockname(AF_INET, &sin, sizeof(sin)))
sin.sin_family = AF_INET;
if (!get_local_sockname(ld, AF_INET, &sin, sizeof(sin)))
return false;
addr->addrlen = sizeof(sin.sin_addr);
memcpy(addr->addr, &sin.sin_addr, addr->addrlen);
@ -245,20 +257,27 @@ static bool guess_one_address(struct wireaddr *addr, u16 portnum,
= {0x20,0x01,0x48,0x60,0x48,0x60,0,0,0,0,0,0,8,8,8,8};
memset(&sin6, 0, sizeof(sin6));
sin6.sin6_port = htons(53);
sin6.sin6_family = AF_INET6;
memcpy(sin6.sin6_addr.s6_addr, pchGoogle, sizeof(pchGoogle));
if (!get_local_sockname(AF_INET6, &sin6, sizeof(sin6)))
if (!get_local_sockname(ld, AF_INET6, &sin6, sizeof(sin6)))
return false;
addr->addrlen = sizeof(sin6.sin6_addr);
memcpy(addr->addr, &sin6.sin6_addr, addr->addrlen);
break;
}
case ADDR_TYPE_PADDING:
log_debug(ld->log, "Padding address, ignoring");
return false;
}
if (!IsRoutable(addr))
if (!IsRoutable(addr)) {
log_debug(ld->log, "Address %s is not routable",
type_to_string(ltmp, struct wireaddr, addr));
return false;
}
log_debug(ld->log, "Public address %s",
type_to_string(ltmp, struct wireaddr, addr));
return true;
}
@ -266,13 +285,15 @@ void guess_addresses(struct lightningd *ld)
{
size_t n = tal_count(ld->wireaddrs);
log_debug(ld->log, "Trying to guess public addresses...");
/* We allocate an extra, then remove if it's not needed. */
tal_resize(&ld->wireaddrs, n+1);
if (guess_one_address(&ld->wireaddrs[n], ld->portnum, ADDR_TYPE_IPV4)) {
if (guess_one_address(ld, &ld->wireaddrs[n], ld->portnum, ADDR_TYPE_IPV4)) {
n++;
tal_resize(&ld->wireaddrs, n+1);
}
if (!guess_one_address(&ld->wireaddrs[n], ld->portnum, ADDR_TYPE_IPV6))
if (!guess_one_address(ld, &ld->wireaddrs[n], ld->portnum, ADDR_TYPE_IPV6))
tal_resize(&ld->wireaddrs, n);
}

10
lightningd/options.c

@ -509,10 +509,6 @@ static void opt_parse_from_config(struct lightningd *ld)
setup_default_config(ld);
opt_parse(&argc, argv, config_log_stderr_exit);
if (ld->portnum && tal_count(ld->wireaddrs) == 0)
guess_addresses(ld);
tal_free(contents);
}
@ -613,6 +609,12 @@ bool handle_opts(struct lightningd *ld, int argc, char *argv[])
check_config(ld);
if (ld->portnum && tal_count(ld->wireaddrs) == 0)
guess_addresses(ld);
else
log_debug(ld->log, "Not guessing addresses: %s",
ld->portnum ? "manually set" : "port set to zero");
#if DEVELOPER
if (ld->dev_hsm_seed) {
int fd;

25
lightningd/peer_control.c

@ -786,28 +786,6 @@ static void log_to_json(unsigned int skipped,
json_add_string(info->response, NULL, log);
}
static const char *wireaddr_name(const tal_t *ctx, const struct wireaddr *a)
{
char name[INET6_ADDRSTRLEN];
int af;
switch (a->type) {
case ADDR_TYPE_IPV4:
af = AF_INET;
break;
case ADDR_TYPE_IPV6:
af = AF_INET6;
break;
default:
return tal_fmt(ctx, "Unknown type %u", a->type);
}
if (!inet_ntop(af, a->addr, name, sizeof(name)))
sprintf(name, "Unprintable-%u-address", a->type);
return tal_fmt(ctx, "%s:%u", name, a->port);
}
static void json_getpeers(struct command *cmd,
const char *buffer, const jsmntok_t *params)
{
@ -839,7 +817,8 @@ 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",
wireaddr_name(response, &p->addr));
type_to_string(response, struct wireaddr,
&p->addr));
json_add_pubkey(response, "peerid", &p->id);
json_add_bool(response, "connected", p->owner != NULL);
if (p->owner)

Loading…
Cancel
Save