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);
|
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:
|
/* Valid forms:
|
||||||
*
|
*
|
||||||
* [anything]:<number>
|
* [anything]:<number>
|
||||||
@@ -148,18 +192,12 @@ bool wireaddr_from_hostname(struct wireaddr *addr, const char *hostname,
|
|||||||
}
|
}
|
||||||
/* Use only the first found address */
|
/* Use only the first found address */
|
||||||
if (addrinfo->ai_family == AF_INET) {
|
if (addrinfo->ai_family == AF_INET) {
|
||||||
addr->type = ADDR_TYPE_IPV4;
|
|
||||||
addr->addrlen = 4;
|
|
||||||
addr->port = port;
|
|
||||||
sa4 = (struct sockaddr_in *) addrinfo->ai_addr;
|
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;
|
res = true;
|
||||||
} else if (addrinfo->ai_family == AF_INET6) {
|
} 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;
|
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;
|
res = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -193,16 +231,10 @@ bool parse_wireaddr(const char *arg, struct wireaddr *addr, u16 defport,
|
|||||||
memset(&addr->addr, 0, sizeof(addr->addr));
|
memset(&addr->addr, 0, sizeof(addr->addr));
|
||||||
|
|
||||||
if (inet_pton(AF_INET, ip, &v4) == 1) {
|
if (inet_pton(AF_INET, ip, &v4) == 1) {
|
||||||
addr->type = ADDR_TYPE_IPV4;
|
wireaddr_from_ipv4(addr, &v4, port);
|
||||||
addr->addrlen = 4;
|
|
||||||
addr->port = port;
|
|
||||||
memcpy(&addr->addr, &v4, addr->addrlen);
|
|
||||||
res = true;
|
res = true;
|
||||||
} else if (inet_pton(AF_INET6, ip, &v6) == 1) {
|
} else if (inet_pton(AF_INET6, ip, &v6) == 1) {
|
||||||
addr->type = ADDR_TYPE_IPV6;
|
wireaddr_from_ipv6(addr, &v6, port);
|
||||||
addr->addrlen = 16;
|
|
||||||
addr->port = port;
|
|
||||||
memcpy(&addr->addr, &v6, addr->addrlen);
|
|
||||||
res = true;
|
res = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,11 @@
|
|||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
struct in6_addr;
|
||||||
|
struct in_addr;
|
||||||
|
struct sockaddr_in6;
|
||||||
|
struct sockaddr_in;
|
||||||
|
|
||||||
/* BOLT #7:
|
/* BOLT #7:
|
||||||
*
|
*
|
||||||
* The following `address descriptor` types are defined:
|
* 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,
|
bool wireaddr_from_hostname(struct wireaddr *addr, const char *hostname,
|
||||||
const u16 port, const char **err_msg);
|
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 */
|
#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) {
|
if (s.ss_family == AF_INET6) {
|
||||||
struct sockaddr_in6 *s6 = (void *)&s;
|
struct sockaddr_in6 *s6 = (void *)&s;
|
||||||
addr.type = ADDR_TYPE_IPV6;
|
wireaddr_from_ipv6(&addr, &s6->sin6_addr, ntohs(s6->sin6_port));
|
||||||
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);
|
|
||||||
} else if (s.ss_family == AF_INET) {
|
} else if (s.ss_family == AF_INET) {
|
||||||
struct sockaddr_in *s4 = (void *)&s;
|
struct sockaddr_in *s4 = (void *)&s;
|
||||||
addr.type = ADDR_TYPE_IPV4;
|
wireaddr_from_ipv4(&addr, &s4->sin_addr, ntohs(s4->sin_port));
|
||||||
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);
|
|
||||||
} else {
|
} else {
|
||||||
status_broken("Unknown socket type %i for incoming conn",
|
status_broken("Unknown socket type %i for incoming conn",
|
||||||
s.ss_family);
|
s.ss_family);
|
||||||
@@ -1568,13 +1560,7 @@ static void setup_listeners(struct daemon *daemon)
|
|||||||
|
|
||||||
switch (daemon->wireaddrs[i].type) {
|
switch (daemon->wireaddrs[i].type) {
|
||||||
case ADDR_TYPE_IPV4:
|
case ADDR_TYPE_IPV4:
|
||||||
addr.sin_family = AF_INET;
|
wireaddr_to_ipv4(&daemon->wireaddrs[i], &addr);
|
||||||
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));
|
|
||||||
/* We might fail if IPv6 bound to port first */
|
/* We might fail if IPv6 bound to port first */
|
||||||
fd = make_listen_fd(AF_INET, &addr, sizeof(addr),
|
fd = make_listen_fd(AF_INET, &addr, sizeof(addr),
|
||||||
!had_ipv6_wildcard);
|
!had_ipv6_wildcard);
|
||||||
@@ -1586,13 +1572,7 @@ static void setup_listeners(struct daemon *daemon)
|
|||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
case ADDR_TYPE_IPV6:
|
case ADDR_TYPE_IPV6:
|
||||||
memset(&addr6, 0, sizeof(addr6));
|
wireaddr_to_ipv6(&daemon->wireaddrs[i], &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));
|
|
||||||
if (memeqzero(&addr6.sin6_addr, sizeof(addr6.sin6_addr)))
|
if (memeqzero(&addr6.sin6_addr, sizeof(addr6.sin6_addr)))
|
||||||
had_ipv6_wildcard = true;
|
had_ipv6_wildcard = true;
|
||||||
fd = make_listen_fd(AF_INET6, &addr6, sizeof(addr6),
|
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) {
|
switch (reach->addr.type) {
|
||||||
case ADDR_TYPE_IPV4:
|
case ADDR_TYPE_IPV4:
|
||||||
ai.ai_family = AF_INET;
|
wireaddr_to_ipv4(&reach->addr, &sin);
|
||||||
sin.sin_family = AF_INET;
|
ai.ai_family = sin.sin_family;
|
||||||
sin.sin_port = htons(reach->addr.port);
|
|
||||||
memcpy(&sin.sin_addr, reach->addr.addr, sizeof(sin.sin_addr));
|
|
||||||
ai.ai_addrlen = sizeof(sin);
|
ai.ai_addrlen = sizeof(sin);
|
||||||
ai.ai_addr = (struct sockaddr *)&sin;
|
ai.ai_addr = (struct sockaddr *)&sin;
|
||||||
break;
|
break;
|
||||||
case ADDR_TYPE_IPV6:
|
case ADDR_TYPE_IPV6:
|
||||||
ai.ai_family = AF_INET6;
|
wireaddr_to_ipv6(&reach->addr, &sin6);
|
||||||
memset(&sin6, 0, sizeof(sin6));
|
ai.ai_family = sin6.sin6_family;
|
||||||
sin6.sin6_family = AF_INET6;
|
|
||||||
sin6.sin6_port = htons(reach->addr.port);
|
|
||||||
memcpy(&sin6.sin6_addr, reach->addr.addr, sizeof(sin6.sin6_addr));
|
|
||||||
ai.ai_addrlen = sizeof(sin6);
|
ai.ai_addrlen = sizeof(sin6);
|
||||||
ai.ai_addr = (struct sockaddr *)&sin6;
|
ai.ai_addr = (struct sockaddr *)&sin6;
|
||||||
break;
|
break;
|
||||||
|
|||||||
Reference in New Issue
Block a user