Browse Source

wireaddr: helpers to convert to/from IPv4/v6 addresses.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
ppa-0.6.1
Rusty Russell 7 years ago
committed by Christian Decker
parent
commit
356e5dcea8
  1. 64
      common/wireaddr.c
  2. 14
      common/wireaddr.h
  3. 41
      gossipd/gossip.c

64
common/wireaddr.c

@ -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;
} }

14
common/wireaddr.h

@ -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 */

41
gossipd/gossip.c

@ -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;

Loading…
Cancel
Save