mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-01-17 19:03:42 +01:00
parent
bd07a91782
commit
f7f55edcdb
@ -72,23 +72,23 @@ int main(void)
|
||||
assert(!separate_address_and_port(ctx, "[::1]:http", &ip, &port));
|
||||
|
||||
// localhost hostnames for backward compat
|
||||
parse_wireaddr("localhost", &addr, 200);
|
||||
parse_wireaddr("localhost", &addr, 200, NULL);
|
||||
assert(addr.port == 200);
|
||||
|
||||
// string should win the port battle
|
||||
parse_wireaddr("[::1]:9735", &addr, 500);
|
||||
parse_wireaddr("[::1]:9735", &addr, 500, NULL);
|
||||
assert(addr.port == 9735);
|
||||
ip = fmt_wireaddr(ctx, &addr);
|
||||
assert(streq(ip, "[::1]:9735"));
|
||||
|
||||
// should use argument if we have no port in string
|
||||
parse_wireaddr("2001:db8:85a3::8a2e:370:7334", &addr, 9777);
|
||||
parse_wireaddr("2001:db8:85a3::8a2e:370:7334", &addr, 9777, NULL);
|
||||
assert(addr.port == 9777);
|
||||
|
||||
ip = fmt_wireaddr(ctx, &addr);
|
||||
assert(streq(ip, "[2001:db8:85a3::8a2e:370:7334]:9777"));
|
||||
|
||||
assert(parse_wireaddr("[::ffff:127.0.0.1]:49150", &addr, 1));
|
||||
assert(parse_wireaddr("[::ffff:127.0.0.1]:49150", &addr, 1, NULL));
|
||||
assert(addr.port == 49150);
|
||||
tal_free(ctx);
|
||||
return 0;
|
||||
|
@ -4,8 +4,10 @@
|
||||
#include <common/type_to_string.h>
|
||||
#include <common/utils.h>
|
||||
#include <common/wireaddr.h>
|
||||
#include <netdb.h>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/types.h>
|
||||
#include <wire/wire.h>
|
||||
|
||||
/* Returns false if we didn't parse it, and *cursor == NULL if malformed. */
|
||||
@ -111,10 +113,16 @@ static bool separate_address_and_port(tal_t *ctx, const char *arg,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool parse_wireaddr(const char *arg, struct wireaddr *addr, u16 defport)
|
||||
bool parse_wireaddr(const char *arg, struct wireaddr *addr, u16 defport,
|
||||
const char **err_msg)
|
||||
{
|
||||
struct in6_addr v6;
|
||||
struct in_addr v4;
|
||||
struct sockaddr_in6 *sa6;
|
||||
struct sockaddr_in *sa4;
|
||||
struct addrinfo *addrinfo;
|
||||
struct addrinfo hints;
|
||||
int gai_err;
|
||||
u16 port;
|
||||
char *ip;
|
||||
bool res;
|
||||
@ -122,13 +130,12 @@ bool parse_wireaddr(const char *arg, struct wireaddr *addr, u16 defport)
|
||||
|
||||
res = false;
|
||||
port = defport;
|
||||
if (err_msg)
|
||||
*err_msg = NULL;
|
||||
|
||||
if (!separate_address_and_port(tmpctx, arg, &ip, &port)) {
|
||||
tal_free(tmpctx);
|
||||
return false;
|
||||
}
|
||||
if (!separate_address_and_port(tmpctx, arg, &ip, &port))
|
||||
goto finish;
|
||||
|
||||
/* FIXME: change arg to addr[:port] and use getaddrinfo? */
|
||||
if (streq(ip, "localhost"))
|
||||
ip = "127.0.0.1";
|
||||
else if (streq(ip, "ip6-localhost"))
|
||||
@ -150,6 +157,44 @@ bool parse_wireaddr(const char *arg, struct wireaddr *addr, u16 defport)
|
||||
res = true;
|
||||
}
|
||||
|
||||
/* Resolve with getaddrinfo */
|
||||
if (!res) {
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_family = AF_UNSPEC;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
hints.ai_protocol = 0;
|
||||
hints.ai_flags = AI_ADDRCONFIG;
|
||||
gai_err = getaddrinfo(ip, tal_fmt(tmpctx, "%d", port),
|
||||
&hints, &addrinfo);
|
||||
if (gai_err != 0) {
|
||||
if (err_msg)
|
||||
*err_msg = gai_strerror(gai_err);
|
||||
goto finish;
|
||||
}
|
||||
/* Use only the first found address */
|
||||
if (addrinfo->ai_family == AF_INET) {
|
||||
addr->type = ADDR_TYPE_IPV4;
|
||||
addr->addrlen = 4;
|
||||
addr->port = port;
|
||||
sa4 = (struct sockaddr_in *) addrinfo->ai_addr;
|
||||
memcpy(&addr->addr, &sa4->sin_addr, addr->addrlen);
|
||||
res = true;
|
||||
} else if (addrinfo->ai_family == AF_INET6) {
|
||||
addr->type = ADDR_TYPE_IPV6;
|
||||
addr->addrlen = 16;
|
||||
addr->port = port;
|
||||
sa6 = (struct sockaddr_in6 *) addrinfo->ai_addr;
|
||||
memcpy(&addr->addr, &sa6->sin6_addr, addr->addrlen);
|
||||
res = true;
|
||||
}
|
||||
|
||||
/* Clean up */
|
||||
freeaddrinfo(addrinfo);
|
||||
}
|
||||
|
||||
finish:
|
||||
if (!res && err_msg && !*err_msg)
|
||||
*err_msg = "Error parsing hostname";
|
||||
tal_free(tmpctx);
|
||||
return res;
|
||||
}
|
||||
|
@ -41,7 +41,7 @@ struct wireaddr {
|
||||
void towire_wireaddr(u8 **pptr, const struct wireaddr *addr);
|
||||
bool fromwire_wireaddr(const u8 **cursor, size_t *max, struct wireaddr *addr);
|
||||
|
||||
bool parse_wireaddr(const char *arg, struct wireaddr *addr, u16 port);
|
||||
bool parse_wireaddr(const char *arg, struct wireaddr *addr, u16 port, const char **err_msg);
|
||||
|
||||
char *fmt_wireaddr(const tal_t *ctx, const struct wireaddr *a);
|
||||
|
||||
|
@ -114,6 +114,7 @@ static void json_connect(struct command *cmd,
|
||||
const char *name;
|
||||
struct wireaddr addr;
|
||||
u8 *msg;
|
||||
const char *err_msg;
|
||||
|
||||
if (!json_get_params(cmd, buffer, params,
|
||||
"id", &idtok,
|
||||
@ -178,9 +179,9 @@ static void json_connect(struct command *cmd,
|
||||
} else {
|
||||
addr.port = DEFAULT_PORT;
|
||||
}
|
||||
if (!parse_wireaddr(name, &addr, addr.port) || !addr.port) {
|
||||
command_fail(cmd, "Host %s:%u not valid",
|
||||
name, addr.port);
|
||||
if (!parse_wireaddr(name, &addr, addr.port, &err_msg) || !addr.port) {
|
||||
command_fail(cmd, "Host %s:%u not valid: %s",
|
||||
name, addr.port, err_msg ? err_msg : "port is 0");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -117,11 +117,12 @@ static char *opt_set_s32(const char *arg, s32 *u)
|
||||
static char *opt_add_ipaddr(const char *arg, struct lightningd *ld)
|
||||
{
|
||||
size_t n = tal_count(ld->wireaddrs);
|
||||
char const *err_msg;
|
||||
|
||||
tal_resize(&ld->wireaddrs, n+1);
|
||||
|
||||
if (!parse_wireaddr(arg, &ld->wireaddrs[n], ld->portnum)) {
|
||||
return tal_fmt(NULL, "Unable to parse IP address '%s'", arg);
|
||||
if (!parse_wireaddr(arg, &ld->wireaddrs[n], ld->portnum, &err_msg)) {
|
||||
return tal_fmt(NULL, "Unable to parse IP address '%s': %s", arg, err_msg);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
@ -436,7 +436,7 @@ static struct peer *wallet_peer_load(struct wallet *w, const u64 dbid)
|
||||
addrstr = sqlite3_column_text(stmt, 2);
|
||||
if (addrstr) {
|
||||
addrp = &addr;
|
||||
if (!parse_wireaddr((const char*)addrstr, addrp, DEFAULT_PORT)) {
|
||||
if (!parse_wireaddr((const char*)addrstr, addrp, DEFAULT_PORT, NULL)) {
|
||||
sqlite3_finalize(stmt);
|
||||
return NULL;
|
||||
}
|
||||
@ -466,7 +466,7 @@ bool wallet_peer_by_nodeid(struct wallet *w, const struct pubkey *nodeid,
|
||||
addrstr = sqlite3_column_text(stmt, 2);
|
||||
|
||||
if (addrstr)
|
||||
parse_wireaddr((const char*)addrstr, &peer->addr, DEFAULT_PORT);
|
||||
parse_wireaddr((const char*)addrstr, &peer->addr, DEFAULT_PORT, NULL);
|
||||
} else {
|
||||
/* Make sure we mark this as a new peer */
|
||||
peer->dbid = 0;
|
||||
|
Loading…
Reference in New Issue
Block a user