diff --git a/gossipd/gossip.c b/gossipd/gossip.c index 1f0594360..5e5883485 100644 --- a/gossipd/gossip.c +++ b/gossipd/gossip.c @@ -47,6 +47,7 @@ #include #include #include +#include #include #include #include @@ -128,7 +129,7 @@ struct daemon { u8 alias[33]; u8 rgb[3]; - struct wireaddr *wireaddrs; + struct wireaddr_internal *wireaddrs; enum addr_listen_announce *listen_announce; /* To make sure our node_announcement timestamps increase */ @@ -149,7 +150,7 @@ struct reaching { struct pubkey id; /* FIXME: Support multiple address. */ - struct wireaddr addr; + struct wireaddr_internal addr; /* Whether connect command is waiting for the result. */ bool master_needs_response; @@ -192,7 +193,7 @@ struct peer { struct pubkey id; /* Where it's connected to. */ - struct wireaddr addr; + struct wireaddr_internal addr; /* Feature bitmaps. */ u8 *gfeatures, *lfeatures; @@ -214,7 +215,7 @@ struct addrhint { struct pubkey id; /* FIXME: use array... */ - struct wireaddr addr; + struct wireaddr_internal addr; }; /* FIXME: Reorder */ @@ -309,7 +310,7 @@ new_local_peer_state(struct peer *peer, const struct crypto_state *cs) static struct peer *new_peer(const tal_t *ctx, struct daemon *daemon, const struct pubkey *their_id, - const struct wireaddr *addr, + const struct wireaddr_internal *addr, const struct crypto_state *cs) { struct peer *peer = tal(ctx, struct peer); @@ -522,7 +523,7 @@ static struct io_plan *read_init(struct io_conn *conn, struct peer *peer) * we have the features. */ static struct io_plan *init_new_peer(struct io_conn *conn, const struct pubkey *their_id, - const struct wireaddr *addr, + const struct wireaddr_internal *addr, const struct crypto_state *cs, struct daemon *daemon) { @@ -566,8 +567,12 @@ static u8 *create_node_announcement(const tal_t *ctx, struct daemon *daemon, memset(sig, 0, sizeof(*sig)); } for (i = 0; i < tal_count(daemon->wireaddrs); i++) { - if (daemon->listen_announce[i] & ADDR_ANNOUNCE) - towire_wireaddr(&addresses, daemon->wireaddrs+i); + if (!(daemon->listen_announce[i] & ADDR_ANNOUNCE)) + continue; + /* You can only announce wiretypes! */ + assert(daemon->wireaddrs[i].itype == ADDR_INTERNAL_WIREADDR); + towire_wireaddr(&addresses, + &daemon->wireaddrs[i].u.wireaddr); } announcement = @@ -1521,7 +1526,7 @@ static void gossip_refresh_network(struct daemon *daemon) static struct io_plan *connection_in(struct io_conn *conn, struct daemon *daemon) { - struct wireaddr addr; + struct wireaddr_internal addr; struct sockaddr_storage s = {}; socklen_t len = sizeof(s); @@ -1533,10 +1538,18 @@ 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; - wireaddr_from_ipv6(&addr, &s6->sin6_addr, ntohs(s6->sin6_port)); + addr.itype = ADDR_INTERNAL_WIREADDR; + wireaddr_from_ipv6(&addr.u.wireaddr, + &s6->sin6_addr, ntohs(s6->sin6_port)); } else if (s.ss_family == AF_INET) { struct sockaddr_in *s4 = (void *)&s; - wireaddr_from_ipv4(&addr, &s4->sin_addr, ntohs(s4->sin_port)); + addr.itype = ADDR_INTERNAL_WIREADDR; + wireaddr_from_ipv4(&addr.u.wireaddr, + &s4->sin_addr, ntohs(s4->sin_port)); + } else if (s.ss_family == AF_UNIX) { + struct sockaddr_un *sun = (void *)&s; + addr.itype = ADDR_INTERNAL_SOCKNAME; + memcpy(addr.u.sockname, sun->sun_path, sizeof(sun->sun_path)); } else { status_broken("Unknown socket type %i for incoming conn", s.ss_family); @@ -1548,50 +1561,78 @@ static struct io_plan *connection_in(struct io_conn *conn, struct daemon *daemon init_new_peer, daemon); } -static void setup_listeners(struct daemon *daemon) +/* Returns true if it was an IPv6 wildcard (as inserted by guess_addresses) */ +static bool handle_wireaddr_listen(struct daemon *daemon, + const struct wireaddr *wireaddr, + bool had_ipv6_wildcard) { - bool had_ipv6_wildcard = false; + int fd; struct sockaddr_in addr; struct sockaddr_in6 addr6; + + switch (wireaddr->type) { + case ADDR_TYPE_IPV4: + wireaddr_to_ipv4(wireaddr, &addr); + /* We might fail if IPv6 bound to port first */ + fd = make_listen_fd(AF_INET, &addr, sizeof(addr), + !had_ipv6_wildcard); + if (fd >= 0) { + status_trace("Created IPv4 listener on port %u", + wireaddr->port); + io_new_listener(daemon, fd, connection_in, daemon); + } + return false; + case ADDR_TYPE_IPV6: + wireaddr_to_ipv6(wireaddr, &addr6); + if (memeqzero(&addr6.sin6_addr, sizeof(addr6.sin6_addr))) + had_ipv6_wildcard = true; + else + had_ipv6_wildcard = false; + fd = make_listen_fd(AF_INET6, &addr6, sizeof(addr6), true); + if (fd >= 0) { + status_trace("Created IPv6 listener on port %u", + wireaddr->port); + io_new_listener(daemon, fd, connection_in, daemon); + } + return had_ipv6_wildcard; + case ADDR_TYPE_PADDING: + break; + } + status_failed(STATUS_FAIL_INTERNAL_ERROR, + "Invalid listener wireaddress type %u", wireaddr->type); +} + +static void setup_listeners(struct daemon *daemon) +{ + bool had_ipv6_wildcard = false; + struct sockaddr_un addrun; int fd; for (size_t i = 0; i < tal_count(daemon->wireaddrs); i++) { if (!(daemon->listen_announce[i] & ADDR_LISTEN)) continue; - switch (daemon->wireaddrs[i].type) { - case ADDR_TYPE_IPV4: - 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); - if (fd >= 0) { - status_trace("Created IPv4 listener on port %u", - daemon->wireaddrs[i].port); - io_new_listener(daemon, fd, connection_in, - daemon); - } + switch (daemon->wireaddrs[i].itype) { + case ADDR_INTERNAL_SOCKNAME: + addrun.sun_family = AF_UNIX; + memcpy(addrun.sun_path, daemon->wireaddrs[i].u.sockname, + sizeof(addrun.sun_path)); + fd = make_listen_fd(AF_INET, &addrun, sizeof(addrun), + false); + status_trace("Created socket listener on file %s", + addrun.sun_path); + io_new_listener(daemon, fd, connection_in, daemon); continue; - case ADDR_TYPE_IPV6: - 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), - true); - if (fd >= 0) { - status_trace("Created IPv6 listener on port %u", - daemon->wireaddrs[i].port); - io_new_listener(daemon, fd, connection_in, - daemon); - } + case ADDR_INTERNAL_WIREADDR: + had_ipv6_wildcard = handle_wireaddr_listen( + daemon, &daemon->wireaddrs[i].u.wireaddr, + had_ipv6_wildcard); continue; - case ADDR_TYPE_PADDING: - break; } /* Shouldn't happen. */ status_failed(STATUS_FAIL_INTERNAL_ERROR, "Invalid listener address type %u", - daemon->wireaddrs[i].type); + daemon->wireaddrs[i].itype); } } @@ -1686,7 +1727,7 @@ static struct io_plan *resolve_channel_req(struct io_conn *conn, static struct io_plan *handshake_out_success(struct io_conn *conn, const struct pubkey *id, - const struct wireaddr *addr, + const struct wireaddr_internal *addr, const struct crypto_state *cs, struct reaching *reach) { @@ -1751,6 +1792,7 @@ static struct io_plan *conn_init(struct io_conn *conn, struct reaching *reach) struct addrinfo ai; struct sockaddr_in sin; struct sockaddr_in6 sin6; + struct sockaddr_un sun; /* FIXME: make generic */ ai.ai_flags = 0; @@ -1759,24 +1801,32 @@ static struct io_plan *conn_init(struct io_conn *conn, struct reaching *reach) ai.ai_canonname = NULL; ai.ai_next = NULL; - switch (reach->addr.type) { - case ADDR_TYPE_IPV4: - wireaddr_to_ipv4(&reach->addr, &sin); - ai.ai_family = sin.sin_family; + switch (reach->addr.itype) { + case ADDR_INTERNAL_SOCKNAME: + wireaddr_to_sockname(&reach->addr, &sun); + ai.ai_family = sun.sun_family; ai.ai_addrlen = sizeof(sin); - ai.ai_addr = (struct sockaddr *)&sin; - break; - case ADDR_TYPE_IPV6: - wireaddr_to_ipv6(&reach->addr, &sin6); - ai.ai_family = sin6.sin6_family; - ai.ai_addrlen = sizeof(sin6); - ai.ai_addr = (struct sockaddr *)&sin6; + ai.ai_addr = (struct sockaddr *)&sun; break; - case ADDR_TYPE_PADDING: - /* Shouldn't happen. */ - return io_close(conn); + case ADDR_INTERNAL_WIREADDR: + switch (reach->addr.u.wireaddr.type) { + case ADDR_TYPE_IPV4: + wireaddr_to_ipv4(&reach->addr.u.wireaddr, &sin); + ai.ai_family = sin.sin_family; + ai.ai_addrlen = sizeof(sin); + ai.ai_addr = (struct sockaddr *)&sin; + break; + case ADDR_TYPE_IPV6: + wireaddr_to_ipv6(&reach->addr.u.wireaddr, &sin6); + ai.ai_family = sin6.sin6_family; + ai.ai_addrlen = sizeof(sin6); + ai.ai_addr = (struct sockaddr *)&sin6; + break; + case ADDR_TYPE_PADDING: + /* Shouldn't happen. */ + return io_close(conn); + } } - io_set_finish(conn, connect_failed, reach); return io_connect(conn, &ai, connection_out, reach); } @@ -1797,12 +1847,14 @@ seed_resolve_addr(const tal_t *ctx, const struct pubkey *id, const u16 port) status_trace("Resolving %s", addr); a = tal(ctx, struct addrhint); - if (!wireaddr_from_hostname(&a->addr, addr, port, NULL)) { + a->addr.itype = ADDR_INTERNAL_WIREADDR; + if (!wireaddr_from_hostname(&a->addr.u.wireaddr, addr, port, NULL)) { status_trace("Could not resolve %s", addr); return tal_free(a); } else { status_trace("Resolved %s to %s", addr, - type_to_string(ctx, struct wireaddr, &a->addr)); + type_to_string(ctx, struct wireaddr, + &a->addr.u.wireaddr)); return a; } } @@ -1830,7 +1882,8 @@ gossip_resolve_addr(const tal_t *ctx, * we should copy all addresses. * For now getting first address should be fine. */ a = tal(ctx, struct addrhint); - a->addr = node->addresses[0]; + a->addr.itype = ADDR_INTERNAL_WIREADDR; + a->addr.u.wireaddr = node->addresses[0]; return a; } @@ -1839,7 +1892,7 @@ static void try_reach_peer(struct daemon *daemon, const struct pubkey *id, bool master_needs_response) { struct addrhint *a; - int fd; + int fd, af; struct reaching *reach; u8 *msg; struct peer *peer = find_peer(daemon, id); @@ -1892,23 +1945,33 @@ static void try_reach_peer(struct daemon *daemon, const struct pubkey *id, } /* Might not even be able to create eg. IPv6 sockets */ - switch (a->addr.type) { - case ADDR_TYPE_IPV4: - fd = socket(AF_INET, SOCK_STREAM, 0); + af = -1; + switch (a->addr.itype) { + case ADDR_INTERNAL_SOCKNAME: + af = AF_LOCAL; break; - case ADDR_TYPE_IPV6: - fd = socket(AF_INET6, SOCK_STREAM, 0); - break; - default: + case ADDR_INTERNAL_WIREADDR: + switch (a->addr.u.wireaddr.type) { + case ADDR_TYPE_IPV4: + af = AF_INET; + break; + case ADDR_TYPE_IPV6: + af = AF_INET6; + break; + case ADDR_TYPE_PADDING: + break; + } + } + if (af == -1) { fd = -1; errno = EPROTONOSUPPORT; - break; - } + } else + fd = socket(af, SOCK_STREAM, 0); if (fd < 0) { char *err = tal_fmt(tmpctx, "Can't open %i socket for %s (%s), giving up", - a->addr.type, + af, type_to_string(tmpctx, struct pubkey, id), strerror(errno)); status_debug("%s", err); @@ -2051,7 +2114,7 @@ static struct io_plan *get_peers(struct io_conn *conn, struct peer *peer; size_t n = 0; struct pubkey *id = tal_arr(conn, struct pubkey, n); - struct wireaddr *wireaddr = tal_arr(conn, struct wireaddr, n); + struct wireaddr_internal *wireaddr = tal_arr(conn, struct wireaddr_internal, n); const struct gossip_getnodes_entry **nodes; struct pubkey *specific_id = NULL; struct node_map_iter it; diff --git a/gossipd/gossip_wire.csv b/gossipd/gossip_wire.csv index 8f781d3fd..c87a8a2e7 100644 --- a/gossipd/gossip_wire.csv +++ b/gossipd/gossip_wire.csv @@ -12,7 +12,7 @@ gossipctl_init,,gfeatures,gflen*u8 gossipctl_init,,lflen,u16 gossipctl_init,,lfeatures,lflen*u8 gossipctl_init,,num_wireaddrs,u16 -gossipctl_init,,wireaddrs,num_wireaddrs*struct wireaddr +gossipctl_init,,wireaddrs,num_wireaddrs*struct wireaddr_internal gossipctl_init,,listen_announce,num_wireaddrs*enum addr_listen_announce gossipctl_init,,rgb,3*u8 gossipctl_init,,alias,32*u8 @@ -30,13 +30,13 @@ gossipctl_activate,,port,u16 # Gossipd->master, I am ready, here are the final addresses. gossipctl_activate_reply,3125 gossipctl_activate_reply,,num_wireaddrs,u16 -gossipctl_activate_reply,,wireaddrs,num_wireaddrs*struct wireaddr +gossipctl_activate_reply,,wireaddrs,num_wireaddrs*struct wireaddr_internal gossipctl_activate_reply,,listen_announce,num_wireaddrs*enum addr_listen_announce # Master -> gossipd: Optional hint for where to find peer. gossipctl_peer_addrhint,3014 gossipctl_peer_addrhint,,id,struct pubkey -gossipctl_peer_addrhint,,addr,struct wireaddr +gossipctl_peer_addrhint,,addr,struct wireaddr_internal # Master -> gossipd: connect to a peer. gossipctl_connect_to_peer,3001 @@ -59,7 +59,7 @@ gossipctl_peer_important,,important,bool # Gossipd -> master: we got a peer. Two fds: peer and gossip gossip_peer_connected,3002 gossip_peer_connected,,id,struct pubkey -gossip_peer_connected,,addr,struct wireaddr +gossip_peer_connected,,addr,struct wireaddr_internal gossip_peer_connected,,crypto_state,struct crypto_state gossip_peer_connected,,gflen,u16 gossip_peer_connected,,gfeatures,gflen*u8 @@ -69,7 +69,7 @@ gossip_peer_connected,,lfeatures,lflen*u8 # Gossipd -> master: peer sent non-gossip packet. Two fds: peer and gossip gossip_peer_nongossip,3003 gossip_peer_nongossip,,id,struct pubkey -gossip_peer_nongossip,,addr,struct wireaddr +gossip_peer_nongossip,,addr,struct wireaddr_internal gossip_peer_nongossip,,crypto_state,struct crypto_state gossip_peer_nongossip,,gflen,u16 gossip_peer_nongossip,,gfeatures,gflen*u8 @@ -84,7 +84,7 @@ gossipctl_release_peer,,id,struct pubkey # Gossipd -> master: reply to gossip_release_peer. Two fds: peer and gossip. gossipctl_release_peer_reply,3104 -gossipctl_release_peer_reply,,addr,struct wireaddr +gossipctl_release_peer_reply,,addr,struct wireaddr_internal gossipctl_release_peer_reply,,crypto_state,struct crypto_state gossipctl_release_peer_reply,,gflen,u16 gossipctl_release_peer_reply,,gfeatures,gflen*u8 @@ -168,7 +168,7 @@ gossip_getpeers_request,,id,num*struct pubkey gossip_getpeers_reply,3111 gossip_getpeers_reply,,num,u16 gossip_getpeers_reply,,id,num*struct pubkey -gossip_getpeers_reply,,addr,num*struct wireaddr +gossip_getpeers_reply,,addr,num*struct wireaddr_internal gossip_getpeers_reply,,numnodes,u16 gossip_getpeers_reply,,nodes,numnodes*struct gossip_getnodes_entry diff --git a/gossipd/handshake.c b/gossipd/handshake.c index 26dbf1c9c..5c9e893c3 100644 --- a/gossipd/handshake.c +++ b/gossipd/handshake.c @@ -170,7 +170,7 @@ struct handshake { struct act_three act3; /* Where is connection from/to */ - struct wireaddr addr; + struct wireaddr_internal addr; /* Who we are */ struct pubkey my_id; @@ -183,7 +183,7 @@ struct handshake { /* Function to call once handshake complete. */ struct io_plan *(*cb)(struct io_conn *conn, const struct pubkey *their_id, - const struct wireaddr *wireaddr, + const struct wireaddr_internal *wireaddr, const struct crypto_state *cs, void *cbarg); void *cbarg; @@ -353,12 +353,12 @@ static struct io_plan *handshake_succeeded(struct io_conn *conn, struct crypto_state cs; struct io_plan *(*cb)(struct io_conn *conn, const struct pubkey *their_id, - const struct wireaddr *addr, + const struct wireaddr_internal *addr, const struct crypto_state *cs, void *cbarg); void *cbarg; struct pubkey their_id; - struct wireaddr addr; + struct wireaddr_internal addr; /* BOLT #8: * @@ -965,10 +965,10 @@ static struct io_plan *act_one_responder(struct io_conn *conn, struct io_plan *responder_handshake_(struct io_conn *conn, const struct pubkey *my_id, - const struct wireaddr *addr, + const struct wireaddr_internal *addr, struct io_plan *(*cb)(struct io_conn *, const struct pubkey *, - const struct wireaddr *, + const struct wireaddr_internal *, const struct crypto_state *, void *cbarg), void *cbarg) @@ -987,10 +987,10 @@ struct io_plan *responder_handshake_(struct io_conn *conn, struct io_plan *initiator_handshake_(struct io_conn *conn, const struct pubkey *my_id, const struct pubkey *their_id, - const struct wireaddr *addr, + const struct wireaddr_internal *addr, struct io_plan *(*cb)(struct io_conn *, const struct pubkey *, - const struct wireaddr *, + const struct wireaddr_internal *, const struct crypto_state *, void *cbarg), void *cbarg) diff --git a/gossipd/handshake.h b/gossipd/handshake.h index fea357fcc..6bc07db32 100644 --- a/gossipd/handshake.h +++ b/gossipd/handshake.h @@ -5,7 +5,7 @@ struct crypto_state; struct io_conn; -struct wireaddr; +struct wireaddr_internal; struct pubkey; #define initiator_handshake(conn, my_id, their_id, addr, cb, cbarg) \ @@ -14,7 +14,7 @@ struct pubkey; (cb), (cbarg), \ struct io_conn *, \ const struct pubkey *, \ - const struct wireaddr *, \ + const struct wireaddr_internal *, \ const struct crypto_state *), \ (cbarg)) @@ -22,10 +22,10 @@ struct pubkey; struct io_plan *initiator_handshake_(struct io_conn *conn, const struct pubkey *my_id, const struct pubkey *their_id, - const struct wireaddr *addr, + const struct wireaddr_internal *addr, struct io_plan *(*cb)(struct io_conn *, const struct pubkey *, - const struct wireaddr *, + const struct wireaddr_internal *, const struct crypto_state *, void *cbarg), void *cbarg); @@ -37,16 +37,16 @@ struct io_plan *initiator_handshake_(struct io_conn *conn, (cb), (cbarg), \ struct io_conn *, \ const struct pubkey *, \ - const struct wireaddr *, \ + const struct wireaddr_internal *, \ const struct crypto_state *), \ (cbarg)) struct io_plan *responder_handshake_(struct io_conn *conn, const struct pubkey *my_id, - const struct wireaddr *addr, + const struct wireaddr_internal *addr, struct io_plan *(*cb)(struct io_conn *, const struct pubkey *, - const struct wireaddr *, + const struct wireaddr_internal *, const struct crypto_state *, void *cbarg), void *cbarg); diff --git a/gossipd/netaddress.c b/gossipd/netaddress.c index 7d23ed012..a7939e970 100644 --- a/gossipd/netaddress.c +++ b/gossipd/netaddress.c @@ -2,7 +2,6 @@ #include #include #include -#include #include #include #include @@ -294,7 +293,7 @@ static enum addr_listen_announce guess_one_address(struct wireaddr *addr, return ret; } -void guess_addresses(struct wireaddr **wireaddrs, +void guess_addresses(struct wireaddr_internal **wireaddrs, enum addr_listen_announce **listen_announce, u16 portnum) { @@ -305,15 +304,18 @@ void guess_addresses(struct wireaddr **wireaddrs, /* We allocate an extra, then remove if it's not needed. */ tal_resize(wireaddrs, n+1); tal_resize(listen_announce, n+1); + + (*wireaddrs)[n].itype = ADDR_INTERNAL_WIREADDR; /* We do IPv6 first: on Linux, that binds to IPv4 too. */ - (*listen_announce)[n] = guess_one_address(&(*wireaddrs)[n], + (*listen_announce)[n] = guess_one_address(&(*wireaddrs)[n].u.wireaddr, portnum, ADDR_TYPE_IPV6); if ((*listen_announce)[n] != 0) { n++; tal_resize(wireaddrs, n+1); tal_resize(listen_announce, n+1); + (*wireaddrs)[n].itype = ADDR_INTERNAL_WIREADDR; } - (*listen_announce)[n] = guess_one_address(&(*wireaddrs)[n], + (*listen_announce)[n] = guess_one_address(&(*wireaddrs)[n].u.wireaddr, portnum, ADDR_TYPE_IPV4); if ((*listen_announce)[n] == 0) { tal_resize(wireaddrs, n); diff --git a/gossipd/netaddress.h b/gossipd/netaddress.h index 68fd2d689..58a3fa25d 100644 --- a/gossipd/netaddress.h +++ b/gossipd/netaddress.h @@ -2,8 +2,9 @@ #define LIGHTNING_GOSSIPD_NETADDRESS_H #include "config.h" #include +#include -void guess_addresses(struct wireaddr **wireaddrs, +void guess_addresses(struct wireaddr_internal **wireaddrs, enum addr_listen_announce **listen_announce, u16 portnum); diff --git a/gossipd/test/run-initiator-success.c b/gossipd/test/run-initiator-success.c index 3932deeac..2efeb4e7d 100644 --- a/gossipd/test/run-initiator-success.c +++ b/gossipd/test/run-initiator-success.c @@ -176,7 +176,7 @@ static struct io_plan *test_read(struct io_conn *conn, static struct io_plan *success(struct io_conn *conn UNUSED, const struct pubkey *them, - const struct wireaddr *addr UNUSED, + const struct wireaddr_internal *addr UNUSED, const struct crypto_state *cs, void *unused UNUSED) { @@ -201,7 +201,7 @@ int main(void) { setup_locale(); - struct wireaddr dummy; + struct wireaddr_internal dummy; secp256k1_ctx = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY | SECP256K1_CONTEXT_SIGN); @@ -223,7 +223,8 @@ int main(void) e_priv = privkey("1212121212121212121212121212121212121212121212121212121212121212"); e_pub = pubkey("036360e856310ce5d294e8be33fc807077dc56ac80d95d9cd4ddbd21325eff73f7"); - dummy.addrlen = 0; + dummy.itype = ADDR_INTERNAL_WIREADDR; + dummy.u.wireaddr.addrlen = 0; initiator_handshake((void *)tmpctx, &ls_pub, &rs_pub, &dummy, success, NULL); /* Should not exit! */ abort(); diff --git a/gossipd/test/run-responder-success.c b/gossipd/test/run-responder-success.c index a65c4c96f..2130edc11 100644 --- a/gossipd/test/run-responder-success.c +++ b/gossipd/test/run-responder-success.c @@ -175,7 +175,7 @@ static struct io_plan *test_read(struct io_conn *conn, static struct io_plan *success(struct io_conn *conn UNUSED, const struct pubkey *them UNUSED, - const struct wireaddr *addr UNUSED, + const struct wireaddr_internal *addr UNUSED, const struct crypto_state *cs, void *unused UNUSED) { @@ -198,7 +198,7 @@ int main(void) { setup_locale(); - struct wireaddr dummy; + struct wireaddr_internal dummy; secp256k1_ctx = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY | SECP256K1_CONTEXT_SIGN); @@ -218,7 +218,8 @@ int main(void) e_priv = privkey("2222222222222222222222222222222222222222222222222222222222222222"); e_pub = pubkey("02466d7fcae563e5cb09a0d1870bb580344804617879a14949cf22285f1bae3f27"); - dummy.addrlen = 0; + dummy.itype = ADDR_INTERNAL_WIREADDR; + dummy.u.wireaddr.addrlen = 0; responder_handshake((void *)tmpctx, &ls_pub, &dummy, success, NULL); /* Should not exit! */ abort(); diff --git a/lightningd/connect_control.c b/lightningd/connect_control.c index 3fa915e3c..05354922d 100644 --- a/lightningd/connect_control.c +++ b/lightningd/connect_control.c @@ -85,7 +85,7 @@ static void json_connect(struct command *cmd, char *atptr; char *ataddr = NULL; const char *name; - struct wireaddr addr; + struct wireaddr_internal addr; u8 *msg; const char *err_msg; @@ -139,22 +139,21 @@ static void json_connect(struct command *cmd, /* Was there parseable host name? */ if (name) { + u32 port; /* Is there a port? */ if (porttok) { - u32 port; - if (!json_tok_number(buffer, porttok, &port)) { + if (!json_tok_number(buffer, porttok, &port) || !port) { command_fail(cmd, "Port %.*s not valid", porttok->end - porttok->start, buffer + porttok->start); return; } - addr.port = port; } else { - addr.port = DEFAULT_PORT; + port = DEFAULT_PORT; } - if (!parse_wireaddr(name, &addr, addr.port, &err_msg) || !addr.port) { + if (!parse_wireaddr_internal(name, &addr, port, &err_msg)) { command_fail(cmd, "Host %s:%u not valid: %s", - name, addr.port, err_msg ? err_msg : "port is 0"); + name, port, err_msg ? err_msg : "port is 0"); return; } diff --git a/lightningd/gossip_control.c b/lightningd/gossip_control.c index aa96e4985..8010622dc 100644 --- a/lightningd/gossip_control.c +++ b/lightningd/gossip_control.c @@ -35,7 +35,7 @@ static void peer_nongossip(struct subd *gossip, const u8 *msg, { struct pubkey id; struct crypto_state cs; - struct wireaddr addr; + struct wireaddr_internal addr; u8 *gfeatures, *lfeatures, *in_pkt; if (!fromwire_gossip_peer_nongossip(msg, msg, diff --git a/lightningd/json.c b/lightningd/json.c index 05ab73bb3..35b5c3c03 100644 --- a/lightningd/json.c +++ b/lightningd/json.c @@ -1,6 +1,7 @@ #include "json.h" #include #include +#include #include #include #include @@ -142,3 +143,20 @@ void json_add_address(struct json_result *response, const char *fieldname, json_object_end(response); } +void json_add_address_internal(struct json_result *response, + const char *fieldname, + const struct wireaddr_internal *addr) +{ + switch (addr->itype) { + case ADDR_INTERNAL_SOCKNAME: + json_object_start(response, fieldname); + json_add_string(response, "type", "local socket"); + json_add_string(response, "socket", addr->u.sockname); + json_object_end(response); + return; + case ADDR_INTERNAL_WIREADDR: + json_add_address(response, fieldname, &addr->u.wireaddr); + return; + } + abort(); +} diff --git a/lightningd/json.h b/lightningd/json.h index 2e4230d3b..29b629884 100644 --- a/lightningd/json.h +++ b/lightningd/json.h @@ -19,6 +19,7 @@ struct route_hop; struct short_channel_id; struct wallet_payment; struct wireaddr; +struct wireaddr_internal; /* Output a route array. */ void json_add_route(struct json_result *r, char const *n, @@ -58,5 +59,8 @@ bool json_tok_channel_id(const char *buffer, const jsmntok_t *tok, void json_add_address(struct json_result *response, const char *fieldname, const struct wireaddr *addr); - +/* JSON serialize a network address for a node. */ +void json_add_address_internal(struct json_result *response, + const char *fieldname, + const struct wireaddr_internal *addr); #endif /* LIGHTNING_LIGHTNINGD_JSON_H */ diff --git a/lightningd/jsonrpc.c b/lightningd/jsonrpc.c index 7ed0709cf..660de3fc8 100644 --- a/lightningd/jsonrpc.c +++ b/lightningd/jsonrpc.c @@ -158,8 +158,8 @@ static void json_getinfo(struct command *cmd, json_array_start(response, "address"); for (size_t i = 0; i < tal_count(cmd->ld->wireaddrs); i++) { if (cmd->ld->listen_announce[i] & ADDR_ANNOUNCE) - json_add_address(response, NULL, - cmd->ld->wireaddrs+i); + json_add_address_internal(response, NULL, + cmd->ld->wireaddrs+i); else have_listen_no_announce = true; } @@ -169,8 +169,8 @@ static void json_getinfo(struct command *cmd, json_array_start(response, "listen-only"); for (size_t i = 0; i < tal_count(cmd->ld->wireaddrs); i++) { if (cmd->ld->listen_announce[i] == ADDR_LISTEN) - json_add_address(response, NULL, - cmd->ld->wireaddrs+i); + json_add_address_internal(response, NULL, + cmd->ld->wireaddrs+i); } json_array_end(response); } diff --git a/lightningd/lightningd.c b/lightningd/lightningd.c index fefc5c976..15b94251b 100644 --- a/lightningd/lightningd.c +++ b/lightningd/lightningd.c @@ -69,7 +69,7 @@ static struct lightningd *new_lightningd(const tal_t *ctx) list_head_init(&ld->waitsendpay_commands); list_head_init(&ld->sendpay_commands); list_head_init(&ld->close_commands); - ld->wireaddrs = tal_arr(ld, struct wireaddr, 0); + ld->wireaddrs = tal_arr(ld, struct wireaddr_internal, 0); ld->listen_announce = tal_arr(ld, enum addr_listen_announce, 0); ld->portnum = DEFAULT_PORT; ld->listen = true; diff --git a/lightningd/lightningd.h b/lightningd/lightningd.h index e60f25e82..bab518a4e 100644 --- a/lightningd/lightningd.h +++ b/lightningd/lightningd.h @@ -121,7 +121,7 @@ struct lightningd { bool autolisten; /* Addresses to bind/announce to the network (tal_count()) */ - struct wireaddr *wireaddrs; + struct wireaddr_internal *wireaddrs; /* And the bitset for each, whether to listen, announce or both */ enum addr_listen_announce *listen_announce; diff --git a/lightningd/opening_control.c b/lightningd/opening_control.c index a6030f118..77f101fd5 100644 --- a/lightningd/opening_control.c +++ b/lightningd/opening_control.c @@ -586,7 +586,7 @@ static struct uncommitted_channel * new_uncommitted_channel(struct lightningd *ld, struct funding_channel *fc, const struct pubkey *peer_id, - const struct wireaddr *addr) + const struct wireaddr_internal *addr) { struct uncommitted_channel *uc = tal(ld, struct uncommitted_channel); char *idname; @@ -671,7 +671,7 @@ static void channel_config(struct lightningd *ld, u8 *peer_accept_channel(const tal_t *ctx, struct lightningd *ld, const struct pubkey *peer_id, - const struct wireaddr *addr, + const struct wireaddr_internal *addr, const struct crypto_state *cs, const u8 *gfeatures UNUSED, const u8 *lfeatures UNUSED, int peer_fd, int gossip_fd, @@ -745,7 +745,7 @@ u8 *peer_accept_channel(const tal_t *ctx, static void peer_offer_channel(struct lightningd *ld, struct funding_channel *fc, - const struct wireaddr *addr, + const struct wireaddr_internal *addr, const struct crypto_state *cs, const u8 *gfeatures UNUSED, const u8 *lfeatures UNUSED, int peer_fd, int gossip_fd) @@ -826,7 +826,7 @@ static void gossip_peer_released(struct subd *gossip, struct lightningd *ld = gossip->ld; struct crypto_state cs; u8 *gfeatures, *lfeatures; - struct wireaddr addr; + struct wireaddr_internal addr; struct channel *c; struct uncommitted_channel *uc; @@ -869,7 +869,7 @@ static void gossip_peer_released(struct subd *gossip, * released. */ bool handle_opening_channel(struct lightningd *ld, const struct pubkey *id, - const struct wireaddr *addr, + const struct wireaddr_internal *addr, const struct crypto_state *cs, const u8 *gfeatures, const u8 *lfeatures, int peer_fd, int gossip_fd) diff --git a/lightningd/opening_control.h b/lightningd/opening_control.h index bbd2781af..eca131dec 100644 --- a/lightningd/opening_control.h +++ b/lightningd/opening_control.h @@ -9,7 +9,7 @@ struct json_result; struct lightningd; struct pubkey; struct uncommitted_channel; -struct wireaddr; +struct wireaddr_internal; void json_add_uncommitted_channel(struct json_result *response, const struct uncommitted_channel *uc); @@ -21,7 +21,7 @@ void json_add_uncommitted_channel(struct json_result *response, u8 *peer_accept_channel(const tal_t *ctx, struct lightningd *ld, const struct pubkey *peer_id, - const struct wireaddr *addr, + const struct wireaddr_internal *addr, const struct crypto_state *cs, const u8 *gfeatures, const u8 *lfeatures, int peer_fd, int gossip_fd, @@ -32,7 +32,7 @@ u8 *peer_accept_channel(const tal_t *ctx, * so we could open a channel? Returns true if it took over. */ bool handle_opening_channel(struct lightningd *ld, const struct pubkey *id, - const struct wireaddr *addr, + const struct wireaddr_internal *addr, const struct crypto_state *cs, const u8 *gfeatures, const u8 *lfeatures, int peer_fd, int gossip_fd); diff --git a/lightningd/options.c b/lightningd/options.c index f6e27f4db..7c32c9dfd 100644 --- a/lightningd/options.c +++ b/lightningd/options.c @@ -158,8 +158,8 @@ static char *opt_add_addr_withtype(const char *arg, tal_resize(&ld->listen_announce, n+1); ld->listen_announce[n] = ala; - 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); + if (!parse_wireaddr_internal(arg, &ld->wireaddrs[n], ld->portnum, &err_msg)) { + return tal_fmt(NULL, "Unable to parse address '%s': %s", arg, err_msg); } return NULL; @@ -828,7 +828,7 @@ static const char *next_name(const char *names, unsigned *len) static void json_add_opt_addrs(struct json_result *response, const char *name0, - const struct wireaddr *wireaddrs, + const struct wireaddr_internal *wireaddrs, const enum addr_listen_announce *listen_announce, enum addr_listen_announce ala) { @@ -837,7 +837,7 @@ static void json_add_opt_addrs(struct json_result *response, continue; json_add_string(response, name0, - fmt_wireaddr(name0, wireaddrs+i)); + fmt_wireaddr_internal(name0, wireaddrs+i)); } } diff --git a/lightningd/peer_control.c b/lightningd/peer_control.c index 3af37ce3b..77b1ad087 100644 --- a/lightningd/peer_control.c +++ b/lightningd/peer_control.c @@ -77,7 +77,7 @@ static void copy_to_parent_log(const char *prefix, struct peer *new_peer(struct lightningd *ld, u64 dbid, const struct pubkey *id, - const struct wireaddr *addr) + const struct wireaddr_internal *addr) { /* We are owned by our channels, and freed manually by destroy_channel */ struct peer *peer = tal(NULL, struct peer); @@ -86,10 +86,13 @@ struct peer *new_peer(struct lightningd *ld, u64 dbid, peer->dbid = dbid; peer->id = *id; peer->uncommitted_channel = NULL; + /* FIXME: This is always set, right? */ if (addr) peer->addr = *addr; - else - peer->addr.type = ADDR_TYPE_PADDING; + else { + peer->addr.itype = ADDR_INTERNAL_WIREADDR; + peer->addr.u.wireaddr.type = ADDR_TYPE_PADDING; + } list_head_init(&peer->channels); peer->direction = get_channel_direction(&peer->ld->id, &peer->id); @@ -423,7 +426,7 @@ void peer_connected(struct lightningd *ld, const u8 *msg, u8 *global_features; u8 *local_features; struct channel *channel; - struct wireaddr addr; + struct wireaddr_internal addr; struct uncommitted_channel *uc; if (!fromwire_gossip_peer_connected(msg, msg, @@ -543,7 +546,7 @@ static struct channel *channel_by_channel_id(struct peer *peer, /* We only get here IF we weren't trying to connect to it. */ void peer_sent_nongossip(struct lightningd *ld, const struct pubkey *id, - const struct wireaddr *addr, + const struct wireaddr_internal *addr, const struct crypto_state *cs, const u8 *gfeatures, const u8 *lfeatures, @@ -745,7 +748,7 @@ static void gossipd_getpeers_complete(struct subd *gossip, const u8 *msg, { /* This is a little sneaky... */ struct pubkey *ids; - struct wireaddr *addrs; + struct wireaddr_internal *addrs; struct gossip_getnodes_entry **nodes; struct json_result *response = new_json_result(gpa->cmd); struct peer *p; @@ -780,10 +783,11 @@ static void gossipd_getpeers_complete(struct subd *gossip, const u8 *msg, if (connected) { json_array_start(response, "netaddr"); - if (p->addr.type != ADDR_TYPE_PADDING) + if (p->addr.itype != ADDR_INTERNAL_WIREADDR + || p->addr.u.wireaddr.type != ADDR_TYPE_PADDING) json_add_string(response, NULL, type_to_string(response, - struct wireaddr, + struct wireaddr_internal, &p->addr)); json_array_end(response); } @@ -921,9 +925,11 @@ static void gossipd_getpeers_complete(struct subd *gossip, const u8 *msg, json_add_pubkey(response, "id", ids+i); json_add_node_decoration(response, nodes, ids+i); json_array_start(response, "netaddr"); - if (addrs[i].type != ADDR_TYPE_PADDING) + if (addrs[i].itype != ADDR_INTERNAL_WIREADDR + || addrs[i].u.wireaddr.type != ADDR_TYPE_PADDING) json_add_string(response, NULL, - type_to_string(response, struct wireaddr, + type_to_string(response, + struct wireaddr_internal, addrs + i)); json_array_end(response); json_add_bool(response, "connected", true); diff --git a/lightningd/peer_control.h b/lightningd/peer_control.h index eb56bcb64..c87bed3f9 100644 --- a/lightningd/peer_control.h +++ b/lightningd/peer_control.h @@ -41,7 +41,7 @@ struct peer { struct log_book *log_book; /* Where we connected to, or it connected from. */ - struct wireaddr addr; + struct wireaddr_internal addr; /* If we open a channel our direction will be this */ u8 direction; @@ -56,7 +56,7 @@ struct peer *find_peer_by_dbid(struct lightningd *ld, u64 dbid); struct peer *new_peer(struct lightningd *ld, u64 dbid, const struct pubkey *id, - const struct wireaddr *addr); + const struct wireaddr_internal *addr); /* Also removes from db. */ void delete_peer(struct peer *peer); @@ -78,7 +78,7 @@ void peer_connected(struct lightningd *ld, const u8 *msg, void peer_sent_nongossip(struct lightningd *ld, const struct pubkey *id, - const struct wireaddr *addr, + const struct wireaddr_internal *addr, const struct crypto_state *cs, const u8 *gfeatures, const u8 *lfeatures, diff --git a/wallet/test/run-wallet.c b/wallet/test/run-wallet.c index 34856bb73..1ed45842f 100644 --- a/wallet/test/run-wallet.c +++ b/wallet/test/run-wallet.c @@ -81,10 +81,10 @@ bool fromwire_gossipctl_peer_disconnect_reply(const void *p UNNEEDED) bool fromwire_gossipctl_peer_disconnect_replyfail(const void *p UNNEEDED, bool *isconnected UNNEEDED) { fprintf(stderr, "fromwire_gossipctl_peer_disconnect_replyfail called!\n"); abort(); } /* Generated stub for fromwire_gossip_getpeers_reply */ -bool fromwire_gossip_getpeers_reply(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, struct pubkey **id UNNEEDED, struct wireaddr **addr UNNEEDED, struct gossip_getnodes_entry ***nodes UNNEEDED) +bool fromwire_gossip_getpeers_reply(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, struct pubkey **id UNNEEDED, struct wireaddr_internal **addr UNNEEDED, struct gossip_getnodes_entry ***nodes UNNEEDED) { fprintf(stderr, "fromwire_gossip_getpeers_reply called!\n"); abort(); } /* Generated stub for fromwire_gossip_peer_connected */ -bool fromwire_gossip_peer_connected(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, struct pubkey *id UNNEEDED, struct wireaddr *addr UNNEEDED, struct crypto_state *crypto_state UNNEEDED, u8 **gfeatures UNNEEDED, u8 **lfeatures UNNEEDED) +bool fromwire_gossip_peer_connected(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, struct pubkey *id UNNEEDED, struct wireaddr_internal *addr UNNEEDED, struct crypto_state *crypto_state UNNEEDED, u8 **gfeatures UNNEEDED, u8 **lfeatures UNNEEDED) { fprintf(stderr, "fromwire_gossip_peer_connected called!\n"); abort(); } /* Generated stub for get_feerate */ u32 get_feerate(const struct chain_topology *topo UNNEEDED, enum feerate feerate UNNEEDED) @@ -98,7 +98,7 @@ u8 *get_offered_local_features(const tal_t *ctx UNNEEDED) /* Generated stub for handle_opening_channel */ bool handle_opening_channel(struct lightningd *ld UNNEEDED, const struct pubkey *id UNNEEDED, - const struct wireaddr *addr UNNEEDED, + const struct wireaddr_internal *addr UNNEEDED, const struct crypto_state *cs UNNEEDED, const u8 *gfeatures UNNEEDED, const u8 *lfeatures UNNEEDED, int peer_fd UNNEEDED, int gossip_fd UNNEEDED) @@ -318,7 +318,7 @@ void outpointfilter_remove(struct outpointfilter *of UNNEEDED, u8 *peer_accept_channel(const tal_t *ctx UNNEEDED, struct lightningd *ld UNNEEDED, const struct pubkey *peer_id UNNEEDED, - const struct wireaddr *addr UNNEEDED, + const struct wireaddr_internal *addr UNNEEDED, const struct crypto_state *cs UNNEEDED, const u8 *gfeatures UNNEEDED, const u8 *lfeatures UNNEEDED, int peer_fd UNNEEDED, int gossip_fd UNNEEDED, @@ -378,7 +378,7 @@ u8 *towire_errorfmt(const tal_t *ctx UNNEEDED, u8 *towire_gossipctl_hand_back_peer(const tal_t *ctx UNNEEDED, const struct pubkey *id UNNEEDED, const struct crypto_state *crypto_state UNNEEDED, const u8 *msg UNNEEDED) { fprintf(stderr, "towire_gossipctl_hand_back_peer called!\n"); abort(); } /* Generated stub for towire_gossipctl_peer_addrhint */ -u8 *towire_gossipctl_peer_addrhint(const tal_t *ctx UNNEEDED, const struct pubkey *id UNNEEDED, const struct wireaddr *addr UNNEEDED) +u8 *towire_gossipctl_peer_addrhint(const tal_t *ctx UNNEEDED, const struct pubkey *id UNNEEDED, const struct wireaddr_internal *addr UNNEEDED) { fprintf(stderr, "towire_gossipctl_peer_addrhint called!\n"); abort(); } /* Generated stub for towire_gossipctl_peer_disconnect */ u8 *towire_gossipctl_peer_disconnect(const tal_t *ctx UNNEEDED, const struct pubkey *id UNNEEDED) diff --git a/wallet/wallet.c b/wallet/wallet.c index e288465c2..548fe3f24 100644 --- a/wallet/wallet.c +++ b/wallet/wallet.c @@ -493,7 +493,7 @@ static struct peer *wallet_peer_load(struct wallet *w, const u64 dbid) const unsigned char *addrstr; struct peer *peer; struct pubkey id; - struct wireaddr *addrp, addr; + struct wireaddr_internal *addrp, addr; sqlite3_stmt *stmt = db_query(w->db, @@ -510,7 +510,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, NULL)) { + if (!parse_wireaddr_internal((const char*)addrstr, addrp, DEFAULT_PORT, NULL)) { db_stmt_done(stmt); return NULL; } @@ -970,11 +970,12 @@ void wallet_channel_insert(struct wallet *w, struct channel *chan) /* Need to create the peer first */ stmt = db_prepare(w->db, "INSERT INTO peers (node_id, address) VALUES (?, ?);"); sqlite3_bind_pubkey(stmt, 1, &chan->peer->id); - if (chan->peer->addr.type == ADDR_TYPE_PADDING) + if (chan->peer->addr.itype == ADDR_INTERNAL_WIREADDR + && chan->peer->addr.u.wireaddr.type == ADDR_TYPE_PADDING) sqlite3_bind_null(stmt, 2); else sqlite3_bind_text(stmt, 2, - type_to_string(tmpctx, struct wireaddr, &chan->peer->addr), + type_to_string(tmpctx, struct wireaddr_internal, &chan->peer->addr), -1, SQLITE_TRANSIENT); db_exec_prepared(w->db, stmt); chan->peer->dbid = sqlite3_last_insert_rowid(w->db->sql);