-
Notifications
You must be signed in to change notification settings - Fork 952
Add support for local socket connections #1323
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -46,6 +46,7 @@ | |
#include <sys/socket.h> | ||
#include <sys/stat.h> | ||
#include <sys/types.h> | ||
#include <sys/un.h> | ||
#include <unistd.h> | ||
#include <wire/gen_peer_wire.h> | ||
#include <wire/wire_io.h> | ||
|
@@ -1541,6 +1542,12 @@ static struct io_plan *connection_in(struct io_conn *conn, struct daemon *daemon | |
BUILD_ASSERT(sizeof(s4->sin_addr) <= sizeof(addr.addr)); | ||
memcpy(addr.addr, &s4->sin_addr, addr.addrlen); | ||
addr.port = ntohs(s4->sin_port); | ||
} else if (s.ss_family == AF_UNIX) { | ||
struct sockaddr_un *sun = (void *)&s; | ||
addr.type = ADDR_TYPE_PADDING; | ||
addr.addrlen = sizeof(sun->sun_path); | ||
memcpy(addr.addr, &sun->sun_path, addr.addrlen); | ||
addr.port = 0; | ||
} else { | ||
status_broken("Unknown socket type %i for incoming conn", | ||
s.ss_family); | ||
|
@@ -1552,12 +1559,13 @@ static struct io_plan *connection_in(struct io_conn *conn, struct daemon *daemon | |
init_new_peer, daemon); | ||
} | ||
|
||
static void setup_listeners(struct daemon *daemon, u16 portnum) | ||
static void setup_listeners(struct daemon *daemon, u16 portnum, const char *localsocket) | ||
{ | ||
struct sockaddr_in addr; | ||
struct sockaddr_in6 addr6; | ||
struct sockaddr_un sun; | ||
socklen_t len; | ||
int fd1, fd2; | ||
int fd1, fd2, fd3; | ||
|
||
if (!portnum) { | ||
status_info("Zero portnum, not listening for incoming"); | ||
|
@@ -1615,6 +1623,27 @@ static void setup_listeners(struct daemon *daemon, u16 portnum) | |
status_failed(STATUS_FAIL_INTERNAL_ERROR, | ||
"Could not bind to a network address on port %u", | ||
portnum); | ||
|
||
/* Optional UNIX socket */ | ||
if (localsocket) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This comes from the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No issue here: turns out 0-length arrays on-the-wire are converted to |
||
memset(&sun, 0, sizeof(sun)); | ||
sun.sun_family = AF_UNIX; | ||
strcpy(sun.sun_path, (char*)localsocket); | ||
|
||
fd3 = make_listen_fd(AF_UNIX, &sun, sizeof(sun), false); | ||
if (fd3 >= 0) { | ||
len = sizeof(sun); | ||
if (getsockname(fd3, (void *)&sun, &len) != 0) { | ||
status_broken("Failed get UNIX sockname: %s", | ||
strerror(errno)); | ||
close_noerr(fd3); | ||
fd3 = -1; | ||
} else { | ||
status_trace("Creating UNIX socket listener"); | ||
io_new_listener(daemon, fd3, connection_in, daemon); | ||
} | ||
} | ||
} | ||
} | ||
|
||
/* Parse an incoming gossip init message and assign config variables | ||
|
@@ -1653,11 +1682,12 @@ static struct io_plan *gossip_activate(struct daemon_conn *master, | |
const u8 *msg) | ||
{ | ||
u16 port; | ||
u8* localsocket; | ||
|
||
if (!fromwire_gossipctl_activate(msg, &port)) | ||
if (!fromwire_gossipctl_activate(msg, msg, &port, &localsocket)) | ||
master_badmsg(WIRE_GOSSIPCTL_ACTIVATE, msg); | ||
|
||
setup_listeners(daemon, port); | ||
setup_listeners(daemon, port, (const char*)localsocket); | ||
|
||
/* OK, we're ready! */ | ||
daemon_conn_send(&daemon->master, | ||
|
@@ -1762,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; | ||
|
@@ -1789,8 +1820,12 @@ static struct io_plan *conn_init(struct io_conn *conn, struct reaching *reach) | |
ai.ai_addr = (struct sockaddr *)&sin6; | ||
break; | ||
case ADDR_TYPE_PADDING: | ||
/* Shouldn't happen. */ | ||
return io_close(conn); | ||
ai.ai_family = AF_UNIX; | ||
sun.sun_family = AF_UNIX; | ||
memcpy(&sun.sun_path, reach->addr.addr, sizeof(sun.sun_path)); | ||
ai.ai_addrlen = sizeof(sun); | ||
ai.ai_addr = (struct sockaddr *)&sun; | ||
break; | ||
} | ||
|
||
io_set_finish(conn, connect_failed, reach); | ||
|
@@ -1915,6 +1950,9 @@ static void try_reach_peer(struct daemon *daemon, const struct pubkey *id, | |
case ADDR_TYPE_IPV6: | ||
fd = socket(AF_INET6, SOCK_STREAM, 0); | ||
break; | ||
case ADDR_TYPE_PADDING: | ||
fd = socket(AF_UNIX, SOCK_STREAM, 0); | ||
break; | ||
default: | ||
fd = -1; | ||
errno = EPROTONOSUPPORT; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -23,6 +23,8 @@ gossipctl_init,,no_reconnect,bool | |
gossipctl_activate,3025 | ||
# If non-zero, port to listen on. | ||
gossipctl_activate,,port,u16 | ||
gossipctl_activate,,lslen,u16 | ||
gossipctl_activate,,localsocket,lslen*u8 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You can use 'wirestring' here, which is much nicer, and removes cast (it's actually a char*, but wirestring is the name for purposes of the csv). |
||
|
||
# Gossipd->master, I am ready. | ||
gossipctl_activate_reply,3125 | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -89,6 +89,9 @@ struct lightningd { | |
char *config_dir; | ||
char *rpc_filename; | ||
|
||
/* Local socket for incoming connections */ | ||
u8 *localsocket_filename; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. char *? |
||
|
||
/* Configuration settings. */ | ||
struct config config; | ||
|
||
|
Original file line number | Diff line number | Diff line change | ||||||||
---|---|---|---|---|---|---|---|---|---|---|
|
@@ -155,6 +155,19 @@ static char *opt_add_ipaddr(const char *arg, struct lightningd *ld) | |||||||||
|
||||||||||
} | ||||||||||
|
||||||||||
static char *opt_add_localsocket(const char *arg, struct lightningd *ld) | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
lightning/lightningd/options.c Lines 874 to 877 in 1a55147
|
||||||||||
{ | ||||||||||
assert(arg != NULL); | ||||||||||
|
||||||||||
ld->localsocket_filename = tal_free(ld->localsocket_filename); | ||||||||||
|
||||||||||
if (strlen(arg) > 108) | ||||||||||
return tal_fmt(NULL, "Local socket path '%s' is over 108 characters", arg); | ||||||||||
ld->localsocket_filename = tal_arrz(ld, u8, strlen(arg)); | ||||||||||
strncpy((char*)ld->localsocket_filename, arg, strlen(arg)); | ||||||||||
return NULL; | ||||||||||
} | ||||||||||
|
||||||||||
static void opt_show_u64(char buf[OPT_SHOW_LEN], const u64 *u) | ||||||||||
{ | ||||||||||
snprintf(buf, OPT_SHOW_LEN, "%"PRIu64, *u); | ||||||||||
|
@@ -319,6 +332,9 @@ static void config_register_opts(struct lightningd *ld) | |||||||||
opt_register_arg("--ipaddr", opt_add_ipaddr, NULL, | ||||||||||
ld, | ||||||||||
"Set the IP address (v4 or v6) to announce to the network for incoming connections"); | ||||||||||
opt_register_arg("--local-socket", opt_add_localsocket, NULL, | ||||||||||
ld, | ||||||||||
"Set a local socket for incoming connections"); | ||||||||||
opt_register_noarg("--offline", opt_set_offline, ld, | ||||||||||
"Start in offline-mode (do not automatically reconnect and do not accept incoming connections"); | ||||||||||
|
||||||||||
|
@@ -859,6 +875,8 @@ static void add_config(struct lightningd *ld, | |||||||||
answer = tal_hexstr(name0, ld->rgb, 3); | ||||||||||
} else if (opt->cb_arg == (void *)opt_set_alias) { | ||||||||||
answer = (const char *)ld->alias; | ||||||||||
} else if (opt->cb_arg == (void *)opt_add_localsocket) { | ||||||||||
answer = (const char *)ld->localsocket_filename; | ||||||||||
} else if (opt->cb_arg == (void *)arg_log_to_file) { | ||||||||||
answer = ld->logfile; | ||||||||||
} else if (opt->cb_arg == (void *)opt_set_fee_rates) { | ||||||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is definitely wrong! We can have things in the msg after the addr. The ADDR_TYPE_PADDING case needs to simply 'return true' (addrlen is 0, there's no port).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
... and set addr->addrlen = 0.