mirror of
https://github.com/aljazceru/lightning.git
synced 2025-12-19 15:14:23 +01:00
wireaddr: helpers to convert to/from IPv4/v6 addresses.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
committed by
Christian Decker
parent
9c0de76019
commit
356e5dcea8
@@ -78,6 +78,50 @@ char *fmt_wireaddr(const tal_t *ctx, const struct wireaddr *a)
|
||||
}
|
||||
REGISTER_TYPE_TO_STRING(wireaddr, fmt_wireaddr);
|
||||
|
||||
void wireaddr_from_ipv4(struct wireaddr *addr,
|
||||
const struct in_addr *ip4,
|
||||
const u16 port)
|
||||
{
|
||||
addr->type = ADDR_TYPE_IPV4;
|
||||
addr->addrlen = sizeof(*ip4);
|
||||
addr->port = port;
|
||||
memset(addr->addr, 0, sizeof(addr->addr));
|
||||
memcpy(addr->addr, ip4, addr->addrlen);
|
||||
}
|
||||
|
||||
void wireaddr_from_ipv6(struct wireaddr *addr,
|
||||
const struct in6_addr *ip6,
|
||||
const u16 port)
|
||||
{
|
||||
addr->type = ADDR_TYPE_IPV6;
|
||||
addr->addrlen = sizeof(*ip6);
|
||||
addr->port = port;
|
||||
memset(addr->addr, 0, sizeof(addr->addr));
|
||||
memcpy(&addr->addr, ip6, addr->addrlen);
|
||||
}
|
||||
|
||||
bool wireaddr_to_ipv4(const struct wireaddr *addr, struct sockaddr_in *s4)
|
||||
{
|
||||
if (addr->type != ADDR_TYPE_IPV4)
|
||||
return false;
|
||||
s4->sin_family = AF_INET;
|
||||
s4->sin_port = htons(addr->port);
|
||||
assert(addr->addrlen == sizeof(s4->sin_addr));
|
||||
memcpy(&s4->sin_addr, addr->addr, sizeof(s4->sin_addr));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool wireaddr_to_ipv6(const struct wireaddr *addr, struct sockaddr_in6 *s6)
|
||||
{
|
||||
if (addr->type != ADDR_TYPE_IPV6)
|
||||
return false;
|
||||
s6->sin6_family = AF_INET6;
|
||||
s6->sin6_port = htons(addr->port);
|
||||
assert(addr->addrlen == sizeof(s6->sin6_addr));
|
||||
memcpy(&s6->sin6_addr, addr->addr, sizeof(s6->sin6_addr));
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Valid forms:
|
||||
*
|
||||
* [anything]:<number>
|
||||
@@ -148,18 +192,12 @@ bool wireaddr_from_hostname(struct wireaddr *addr, const char *hostname,
|
||||
}
|
||||
/* 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);
|
||||
wireaddr_from_ipv4(addr, &sa4->sin_addr, port);
|
||||
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);
|
||||
wireaddr_from_ipv6(addr, &sa6->sin6_addr, port);
|
||||
res = true;
|
||||
}
|
||||
|
||||
@@ -193,16 +231,10 @@ bool parse_wireaddr(const char *arg, struct wireaddr *addr, u16 defport,
|
||||
memset(&addr->addr, 0, sizeof(addr->addr));
|
||||
|
||||
if (inet_pton(AF_INET, ip, &v4) == 1) {
|
||||
addr->type = ADDR_TYPE_IPV4;
|
||||
addr->addrlen = 4;
|
||||
addr->port = port;
|
||||
memcpy(&addr->addr, &v4, addr->addrlen);
|
||||
wireaddr_from_ipv4(addr, &v4, port);
|
||||
res = true;
|
||||
} else if (inet_pton(AF_INET6, ip, &v6) == 1) {
|
||||
addr->type = ADDR_TYPE_IPV6;
|
||||
addr->addrlen = 16;
|
||||
addr->port = port;
|
||||
memcpy(&addr->addr, &v6, addr->addrlen);
|
||||
wireaddr_from_ipv6(addr, &v6, port);
|
||||
res = true;
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,11 @@
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
struct in6_addr;
|
||||
struct in_addr;
|
||||
struct sockaddr_in6;
|
||||
struct sockaddr_in;
|
||||
|
||||
/* BOLT #7:
|
||||
*
|
||||
* The following `address descriptor` types are defined:
|
||||
@@ -60,4 +65,13 @@ char *fmt_wireaddr(const tal_t *ctx, const struct wireaddr *a);
|
||||
bool wireaddr_from_hostname(struct wireaddr *addr, const char *hostname,
|
||||
const u16 port, const char **err_msg);
|
||||
|
||||
void wireaddr_from_ipv4(struct wireaddr *addr,
|
||||
const struct in_addr *ip4,
|
||||
const u16 port);
|
||||
void wireaddr_from_ipv6(struct wireaddr *addr,
|
||||
const struct in6_addr *ip6,
|
||||
const u16 port);
|
||||
bool wireaddr_to_ipv4(const struct wireaddr *addr, struct sockaddr_in *s4);
|
||||
bool wireaddr_to_ipv6(const struct wireaddr *addr, struct sockaddr_in6 *s6);
|
||||
|
||||
#endif /* LIGHTNING_COMMON_WIREADDR_H */
|
||||
|
||||
@@ -1532,18 +1532,10 @@ static struct io_plan *connection_in(struct io_conn *conn, struct daemon *daemon
|
||||
|
||||
if (s.ss_family == AF_INET6) {
|
||||
struct sockaddr_in6 *s6 = (void *)&s;
|
||||
addr.type = ADDR_TYPE_IPV6;
|
||||
addr.addrlen = sizeof(s6->sin6_addr);
|
||||
BUILD_ASSERT(sizeof(s6->sin6_addr) <= sizeof(addr.addr));
|
||||
memcpy(addr.addr, &s6->sin6_addr, addr.addrlen);
|
||||
addr.port = ntohs(s6->sin6_port);
|
||||
wireaddr_from_ipv6(&addr, &s6->sin6_addr, ntohs(s6->sin6_port));
|
||||
} else if (s.ss_family == AF_INET) {
|
||||
struct sockaddr_in *s4 = (void *)&s;
|
||||
addr.type = ADDR_TYPE_IPV4;
|
||||
addr.addrlen = sizeof(s4->sin_addr);
|
||||
BUILD_ASSERT(sizeof(s4->sin_addr) <= sizeof(addr.addr));
|
||||
memcpy(addr.addr, &s4->sin_addr, addr.addrlen);
|
||||
addr.port = ntohs(s4->sin_port);
|
||||
wireaddr_from_ipv4(&addr, &s4->sin_addr, ntohs(s4->sin_port));
|
||||
} else {
|
||||
status_broken("Unknown socket type %i for incoming conn",
|
||||
s.ss_family);
|
||||
@@ -1568,13 +1560,7 @@ static void setup_listeners(struct daemon *daemon)
|
||||
|
||||
switch (daemon->wireaddrs[i].type) {
|
||||
case ADDR_TYPE_IPV4:
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = htons(daemon->wireaddrs[i].port);
|
||||
assert(daemon->wireaddrs[i].addrlen
|
||||
== sizeof(addr.sin_addr));
|
||||
memcpy(&addr.sin_addr,
|
||||
daemon->wireaddrs[i].addr,
|
||||
sizeof(addr.sin_addr));
|
||||
wireaddr_to_ipv4(&daemon->wireaddrs[i], &addr);
|
||||
/* We might fail if IPv6 bound to port first */
|
||||
fd = make_listen_fd(AF_INET, &addr, sizeof(addr),
|
||||
!had_ipv6_wildcard);
|
||||
@@ -1586,13 +1572,7 @@ static void setup_listeners(struct daemon *daemon)
|
||||
}
|
||||
continue;
|
||||
case ADDR_TYPE_IPV6:
|
||||
memset(&addr6, 0, sizeof(addr6));
|
||||
addr6.sin6_family = AF_INET6;
|
||||
addr6.sin6_port = htons(daemon->wireaddrs[i].port);
|
||||
assert(daemon->wireaddrs[i].addrlen
|
||||
== sizeof(addr6.sin6_addr));
|
||||
memcpy(&addr6.sin6_addr, daemon->wireaddrs[i].addr,
|
||||
sizeof(addr6.sin6_addr));
|
||||
wireaddr_to_ipv6(&daemon->wireaddrs[i], &addr6);
|
||||
if (memeqzero(&addr6.sin6_addr, sizeof(addr6.sin6_addr)))
|
||||
had_ipv6_wildcard = true;
|
||||
fd = make_listen_fd(AF_INET6, &addr6, sizeof(addr6),
|
||||
@@ -1771,19 +1751,14 @@ static struct io_plan *conn_init(struct io_conn *conn, struct reaching *reach)
|
||||
|
||||
switch (reach->addr.type) {
|
||||
case ADDR_TYPE_IPV4:
|
||||
ai.ai_family = AF_INET;
|
||||
sin.sin_family = AF_INET;
|
||||
sin.sin_port = htons(reach->addr.port);
|
||||
memcpy(&sin.sin_addr, reach->addr.addr, sizeof(sin.sin_addr));
|
||||
wireaddr_to_ipv4(&reach->addr, &sin);
|
||||
ai.ai_family = sin.sin_family;
|
||||
ai.ai_addrlen = sizeof(sin);
|
||||
ai.ai_addr = (struct sockaddr *)&sin;
|
||||
break;
|
||||
case ADDR_TYPE_IPV6:
|
||||
ai.ai_family = AF_INET6;
|
||||
memset(&sin6, 0, sizeof(sin6));
|
||||
sin6.sin6_family = AF_INET6;
|
||||
sin6.sin6_port = htons(reach->addr.port);
|
||||
memcpy(&sin6.sin6_addr, reach->addr.addr, sizeof(sin6.sin6_addr));
|
||||
wireaddr_to_ipv6(&reach->addr, &sin6);
|
||||
ai.ai_family = sin6.sin6_family;
|
||||
ai.ai_addrlen = sizeof(sin6);
|
||||
ai.ai_addr = (struct sockaddr *)&sin6;
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user