lightningd: allow --bind=ws:

Changelog-Added: Config: `bind=ws:...` to explicitly listen on a websocket.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
Rusty Russell 2023-05-30 13:58:18 +09:30
parent a6772e9dec
commit 3d5367278b
3 changed files with 65 additions and 3 deletions

View file

@ -232,6 +232,50 @@ int main(int argc, char *argv[])
strcpy(expect->u.sockname, "/tmp/foo.sock");
assert(wireaddr_internal_eq(&addr, expect));
/* Websocket (only for IP addresses) */
assert(parse_wireaddr_internal(tmpctx, "ws:/tmp/foo.sock", DEFAULT_PORT, false, &addr) != NULL);
assert(parse_wireaddr_internal(tmpctx, "ws:127.0.0.1", DEFAULT_PORT, false, &addr) == NULL);
expect->itype = ADDR_INTERNAL_WIREADDR;
expect->u.wireaddr.is_websocket = true;
assert(parse_wireaddr(tmpctx, "127.0.0.1:9735", 0, NULL, &expect->u.wireaddr.wireaddr) == NULL);
assert(wireaddr_internal_eq(&addr, expect));
/* Websocket: IPv4 address with port. */
assert(parse_wireaddr_internal(tmpctx, "ws:127.0.0.1:1", DEFAULT_PORT, false, &addr) == NULL);
expect->itype = ADDR_INTERNAL_WIREADDR;
expect->u.wireaddr.is_websocket = true;
assert(parse_wireaddr(tmpctx, "127.0.0.1:1", 0, NULL, &expect->u.wireaddr.wireaddr) == NULL);
assert(wireaddr_internal_eq(&addr, expect));
/* Websocket: Simple IPv6 address. */
assert(parse_wireaddr_internal(tmpctx, "ws:::1", DEFAULT_PORT, false, &addr) == NULL);
expect->itype = ADDR_INTERNAL_WIREADDR;
expect->u.wireaddr.is_websocket = true;
assert(parse_wireaddr(tmpctx, "::1", DEFAULT_PORT, NULL, &expect->u.wireaddr.wireaddr) == NULL);
assert(wireaddr_internal_eq(&addr, expect));
/* Websocket: IPv6 address with port. */
assert(parse_wireaddr_internal(tmpctx, "ws:[::1]:1", DEFAULT_PORT, false, &addr) == NULL);
expect->itype = ADDR_INTERNAL_WIREADDR;
expect->u.wireaddr.is_websocket = true;
assert(parse_wireaddr(tmpctx, "::1", 1, NULL, &expect->u.wireaddr.wireaddr) == NULL);
assert(wireaddr_internal_eq(&addr, expect));
/* Websocket: IPv4 & v6 address. */
assert(parse_wireaddr_internal(tmpctx, "ws:", DEFAULT_PORT, false, &addr) == NULL);
expect->itype = ADDR_INTERNAL_ALLPROTO;
expect->u.allproto.is_websocket = true;
expect->u.allproto.port = DEFAULT_PORT;
assert(wireaddr_internal_eq(&addr, expect));
/* Websocket: IPv4 & v6 address with port */
assert(parse_wireaddr_internal(tmpctx, "ws::1", DEFAULT_PORT, false, &addr) == NULL);
expect->itype = ADDR_INTERNAL_ALLPROTO;
expect->u.allproto.is_websocket = true;
expect->u.allproto.port = 1;
assert(wireaddr_internal_eq(&addr, expect));
/* Unresolved */
assert(parse_wireaddr_internal(tmpctx, "ozlabs.org", DEFAULT_PORT, false, &addr) == NULL);
expect->itype = ADDR_INTERNAL_FORPROXY;

View file

@ -614,7 +614,7 @@ const char *parse_wireaddr_internal(const tal_t *ctx,
char *ip;
char *service_addr;
const char *err;
bool needed_dns;
bool needed_dns, is_websocket;
/* Addresses starting with '/' are local socket paths */
if (arg[0] == '/') {
@ -697,6 +697,14 @@ const char *parse_wireaddr_internal(const tal_t *ctx,
&addr->u.torservice.address);
}
/* Do this before we get to separate_address_and_port! */
if (strstarts(arg, "ws:")) {
arg += 3;
is_websocket = true;
} else {
is_websocket = false;
}
/* This can fail, but that may be OK! */
splitport = default_port;
if (!separate_address_and_port(tmpctx, arg, &ip, &splitport))
@ -706,7 +714,7 @@ const char *parse_wireaddr_internal(const tal_t *ctx,
* means just IPv6, and IPv4 gets autobound). */
if (ip && streq(ip, "")) {
addr->itype = ADDR_INTERNAL_ALLPROTO;
addr->u.allproto.is_websocket = false;
addr->u.allproto.is_websocket = is_websocket;
addr->u.allproto.port = splitport;
return NULL;
}
@ -717,7 +725,7 @@ const char *parse_wireaddr_internal(const tal_t *ctx,
&addr->u.wireaddr.wireaddr);
if (!err) {
addr->itype = ADDR_INTERNAL_WIREADDR;
addr->u.wireaddr.is_websocket = false;
addr->u.wireaddr.is_websocket = is_websocket;
return NULL;
}
@ -729,6 +737,9 @@ const char *parse_wireaddr_internal(const tal_t *ctx,
if (!ip)
return "Malformed port";
if (is_websocket)
return "Could not resolve websocket address";
/* Keep unresolved. */
tal_free(err);
if (!wireaddr_from_unresolved(addr, ip, splitport))

View file

@ -271,6 +271,9 @@ static char *opt_add_addr_withtype(const char *arg,
switch (wi.u.wireaddr.wireaddr.type) {
case ADDR_TYPE_IPV4:
case ADDR_TYPE_IPV6:
if ((ala & ADDR_ANNOUNCE) && wi.u.allproto.is_websocket)
return tal_fmt(NULL,
"Cannot announce websocket address, use --bind-addr=%s", arg);
/* These can be either bind or announce */
break;
case ADDR_TYPE_TOR_V2_REMOVED:
@ -363,6 +366,10 @@ static char *opt_add_addr_withtype(const char *arg,
case ADDR_ANNOUNCE:
return tal_fmt(NULL, "Cannot use wildcard address '%s'", arg);
case ADDR_LISTEN_AND_ANNOUNCE:
if (wi.u.allproto.is_websocket)
return tal_fmt(NULL,
"Cannot announce websocket address, use --bind-addr=%s", arg);
/* fall thru */
case ADDR_LISTEN:
break;
}