mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-02-20 13:54:36 +01:00
common: add new internal type for websockets.
Now it's not a public type, we need a way to refer to it. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
parent
7b843e8e58
commit
a6772e9dec
21 changed files with 285 additions and 126 deletions
|
@ -63,7 +63,8 @@
|
|||
"ipv6": 2,
|
||||
"local socket": 0,
|
||||
"torv2": 3,
|
||||
"torv3": 4
|
||||
"torv3": 4,
|
||||
"websocket": 5
|
||||
},
|
||||
"GetrouteRouteStyle": {
|
||||
"tlv": 0
|
||||
|
|
1
cln-grpc/proto/node.proto
generated
1
cln-grpc/proto/node.proto
generated
|
@ -113,6 +113,7 @@ message GetinfoBinding {
|
|||
// Getinfo.binding[].type
|
||||
enum GetinfoBindingType {
|
||||
LOCAL_SOCKET = 0;
|
||||
WEBSOCKET = 5;
|
||||
IPV4 = 1;
|
||||
IPV6 = 2;
|
||||
TORV2 = 3;
|
||||
|
|
11
cln-rpc/src/model.rs
generated
11
cln-rpc/src/model.rs
generated
|
@ -1476,6 +1476,8 @@ pub mod responses {
|
|||
pub enum GetinfoBindingType {
|
||||
#[serde(rename = "local socket")]
|
||||
LOCAL_SOCKET,
|
||||
#[serde(rename = "websocket")]
|
||||
WEBSOCKET,
|
||||
#[serde(rename = "ipv4")]
|
||||
IPV4,
|
||||
#[serde(rename = "ipv6")]
|
||||
|
@ -1491,10 +1493,11 @@ pub mod responses {
|
|||
fn try_from(c: i32) -> Result<GetinfoBindingType, anyhow::Error> {
|
||||
match c {
|
||||
0 => Ok(GetinfoBindingType::LOCAL_SOCKET),
|
||||
1 => Ok(GetinfoBindingType::IPV4),
|
||||
2 => Ok(GetinfoBindingType::IPV6),
|
||||
3 => Ok(GetinfoBindingType::TORV2),
|
||||
4 => Ok(GetinfoBindingType::TORV3),
|
||||
1 => Ok(GetinfoBindingType::WEBSOCKET),
|
||||
2 => Ok(GetinfoBindingType::IPV4),
|
||||
3 => Ok(GetinfoBindingType::IPV6),
|
||||
4 => Ok(GetinfoBindingType::TORV2),
|
||||
5 => Ok(GetinfoBindingType::TORV3),
|
||||
o => Err(anyhow::anyhow!("Unknown variant {} for enum GetinfoBindingType", o)),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -493,35 +493,54 @@ void json_add_short_channel_id(struct json_stream *response,
|
|||
short_channel_id_outnum(scid));
|
||||
}
|
||||
|
||||
static void json_add_address_fields(struct json_stream *response,
|
||||
const struct wireaddr *addr,
|
||||
const char *typefield)
|
||||
{
|
||||
switch (addr->type) {
|
||||
case ADDR_TYPE_IPV4: {
|
||||
char addrstr[INET_ADDRSTRLEN];
|
||||
inet_ntop(AF_INET, addr->addr, addrstr, INET_ADDRSTRLEN);
|
||||
json_add_string(response, typefield, "ipv4");
|
||||
json_add_string(response, "address", addrstr);
|
||||
json_add_num(response, "port", addr->port);
|
||||
return;
|
||||
}
|
||||
case ADDR_TYPE_IPV6: {
|
||||
char addrstr[INET6_ADDRSTRLEN];
|
||||
inet_ntop(AF_INET6, addr->addr, addrstr, INET6_ADDRSTRLEN);
|
||||
json_add_string(response, typefield, "ipv6");
|
||||
json_add_string(response, "address", addrstr);
|
||||
json_add_num(response, "port", addr->port);
|
||||
return;
|
||||
}
|
||||
case ADDR_TYPE_TOR_V2_REMOVED: {
|
||||
json_add_string(response, typefield, "torv2");
|
||||
json_add_string(response, "address", fmt_wireaddr_without_port(tmpctx, addr));
|
||||
json_add_num(response, "port", addr->port);
|
||||
return;
|
||||
}
|
||||
case ADDR_TYPE_TOR_V3: {
|
||||
json_add_string(response, typefield, "torv3");
|
||||
json_add_string(response, "address", fmt_wireaddr_without_port(tmpctx, addr));
|
||||
json_add_num(response, "port", addr->port);
|
||||
return;
|
||||
}
|
||||
case ADDR_TYPE_DNS: {
|
||||
json_add_string(response, typefield, "dns");
|
||||
json_add_string(response, "address", fmt_wireaddr_without_port(tmpctx, addr));
|
||||
json_add_num(response, "port", addr->port);
|
||||
return;
|
||||
}
|
||||
}
|
||||
abort();
|
||||
}
|
||||
|
||||
void json_add_address(struct json_stream *response, const char *fieldname,
|
||||
const struct wireaddr *addr)
|
||||
{
|
||||
json_object_start(response, fieldname);
|
||||
if (addr->type == ADDR_TYPE_IPV4) {
|
||||
char addrstr[INET_ADDRSTRLEN];
|
||||
inet_ntop(AF_INET, addr->addr, addrstr, INET_ADDRSTRLEN);
|
||||
json_add_string(response, "type", "ipv4");
|
||||
json_add_string(response, "address", addrstr);
|
||||
json_add_num(response, "port", addr->port);
|
||||
} else if (addr->type == ADDR_TYPE_IPV6) {
|
||||
char addrstr[INET6_ADDRSTRLEN];
|
||||
inet_ntop(AF_INET6, addr->addr, addrstr, INET6_ADDRSTRLEN);
|
||||
json_add_string(response, "type", "ipv6");
|
||||
json_add_string(response, "address", addrstr);
|
||||
json_add_num(response, "port", addr->port);
|
||||
} else if (addr->type == ADDR_TYPE_TOR_V2_REMOVED) {
|
||||
json_add_string(response, "type", "torv2");
|
||||
json_add_string(response, "address", fmt_wireaddr_without_port(tmpctx, addr));
|
||||
json_add_num(response, "port", addr->port);
|
||||
} else if (addr->type == ADDR_TYPE_TOR_V3) {
|
||||
json_add_string(response, "type", "torv3");
|
||||
json_add_string(response, "address", fmt_wireaddr_without_port(tmpctx, addr));
|
||||
json_add_num(response, "port", addr->port);
|
||||
} else if (addr->type == ADDR_TYPE_DNS) {
|
||||
json_add_string(response, "type", "dns");
|
||||
json_add_string(response, "address", fmt_wireaddr_without_port(tmpctx, addr));
|
||||
json_add_num(response, "port", addr->port);
|
||||
}
|
||||
json_add_address_fields(response, addr, "type");
|
||||
json_object_end(response);
|
||||
}
|
||||
|
||||
|
@ -538,8 +557,13 @@ void json_add_address_internal(struct json_stream *response,
|
|||
return;
|
||||
case ADDR_INTERNAL_ALLPROTO:
|
||||
json_object_start(response, fieldname);
|
||||
json_add_string(response, "type", "any protocol");
|
||||
json_add_num(response, "port", addr->u.port);
|
||||
if (addr->u.allproto.is_websocket) {
|
||||
json_add_string(response, "type", "websocket");
|
||||
json_add_string(response, "subtype", "any protocol");
|
||||
} else {
|
||||
json_add_string(response, "type", "any protocol");
|
||||
}
|
||||
json_add_num(response, "port", addr->u.allproto.port);
|
||||
json_object_end(response);
|
||||
return;
|
||||
case ADDR_INTERNAL_AUTOTOR:
|
||||
|
@ -562,7 +586,14 @@ void json_add_address_internal(struct json_stream *response,
|
|||
json_object_end(response);
|
||||
return;
|
||||
case ADDR_INTERNAL_WIREADDR:
|
||||
json_add_address(response, fieldname, &addr->u.wireaddr);
|
||||
json_object_start(response, fieldname);
|
||||
if (addr->u.wireaddr.is_websocket) {
|
||||
json_add_string(response, "type", "websocket");
|
||||
json_add_address_fields(response, &addr->u.wireaddr.wireaddr, "subtype");
|
||||
} else {
|
||||
json_add_address_fields(response, &addr->u.wireaddr.wireaddr, "type");
|
||||
}
|
||||
json_object_end(response);
|
||||
return;
|
||||
}
|
||||
abort();
|
||||
|
|
|
@ -134,25 +134,29 @@ int main(int argc, char *argv[])
|
|||
/* Simple IPv4 address. */
|
||||
assert(parse_wireaddr_internal(tmpctx, "127.0.0.1", DEFAULT_PORT, false, &addr) == NULL);
|
||||
expect->itype = ADDR_INTERNAL_WIREADDR;
|
||||
assert(parse_wireaddr(tmpctx, "127.0.0.1:9735", 0, NULL, &expect->u.wireaddr) == NULL);
|
||||
expect->u.wireaddr.is_websocket = false;
|
||||
assert(parse_wireaddr(tmpctx, "127.0.0.1:9735", 0, NULL, &expect->u.wireaddr.wireaddr) == NULL);
|
||||
assert(wireaddr_internal_eq(&addr, expect));
|
||||
|
||||
/* IPv4 address with port. */
|
||||
assert(parse_wireaddr_internal(tmpctx, "127.0.0.1:1", DEFAULT_PORT, false, &addr) == NULL);
|
||||
expect->itype = ADDR_INTERNAL_WIREADDR;
|
||||
assert(parse_wireaddr(tmpctx, "127.0.0.1:1", 0, NULL, &expect->u.wireaddr) == NULL);
|
||||
expect->u.wireaddr.is_websocket = false;
|
||||
assert(parse_wireaddr(tmpctx, "127.0.0.1:1", 0, NULL, &expect->u.wireaddr.wireaddr) == NULL);
|
||||
assert(wireaddr_internal_eq(&addr, expect));
|
||||
|
||||
/* Simple IPv6 address. */
|
||||
assert(parse_wireaddr_internal(tmpctx, "::1", DEFAULT_PORT, false, &addr) == NULL);
|
||||
expect->itype = ADDR_INTERNAL_WIREADDR;
|
||||
assert(parse_wireaddr(tmpctx, "::1", DEFAULT_PORT, NULL, &expect->u.wireaddr) == NULL);
|
||||
expect->u.wireaddr.is_websocket = false;
|
||||
assert(parse_wireaddr(tmpctx, "::1", DEFAULT_PORT, NULL, &expect->u.wireaddr.wireaddr) == NULL);
|
||||
assert(wireaddr_internal_eq(&addr, expect));
|
||||
|
||||
/* IPv6 address with port. */
|
||||
assert(parse_wireaddr_internal(tmpctx, "[::1]:1", DEFAULT_PORT, false, &addr) == NULL);
|
||||
expect->itype = ADDR_INTERNAL_WIREADDR;
|
||||
assert(parse_wireaddr(tmpctx, "::1", 1, NULL, &expect->u.wireaddr) == NULL);
|
||||
expect->u.wireaddr.is_websocket = false;
|
||||
assert(parse_wireaddr(tmpctx, "::1", 1, NULL, &expect->u.wireaddr.wireaddr) == NULL);
|
||||
assert(wireaddr_internal_eq(&addr, expect));
|
||||
|
||||
/* autotor address */
|
||||
|
|
|
@ -98,10 +98,12 @@ void towire_wireaddr_internal(u8 **pptr, const struct wireaddr_internal *addr)
|
|||
towire_u16(pptr, addr->u.torservice.port);
|
||||
return;
|
||||
case ADDR_INTERNAL_ALLPROTO:
|
||||
towire_u16(pptr, addr->u.port);
|
||||
towire_bool(pptr, addr->u.allproto.is_websocket);
|
||||
towire_u16(pptr, addr->u.allproto.port);
|
||||
return;
|
||||
case ADDR_INTERNAL_WIREADDR:
|
||||
towire_wireaddr(pptr, &addr->u.wireaddr);
|
||||
towire_bool(pptr, addr->u.wireaddr.is_websocket);
|
||||
towire_wireaddr(pptr, &addr->u.wireaddr.wireaddr);
|
||||
return;
|
||||
case ADDR_INTERNAL_FORPROXY:
|
||||
towire_u8_array(pptr, (const u8 *)addr->u.unresolved.name,
|
||||
|
@ -125,7 +127,8 @@ bool fromwire_wireaddr_internal(const u8 **cursor, size_t *max,
|
|||
fromwire_fail(cursor, max);
|
||||
return *cursor != NULL;
|
||||
case ADDR_INTERNAL_ALLPROTO:
|
||||
addr->u.port = fromwire_u16(cursor, max);
|
||||
addr->u.allproto.is_websocket = fromwire_bool(cursor, max);
|
||||
addr->u.allproto.port = fromwire_u16(cursor, max);
|
||||
return *cursor != NULL;
|
||||
case ADDR_INTERNAL_AUTOTOR:
|
||||
fromwire_wireaddr(cursor, max, &addr->u.torservice.address);
|
||||
|
@ -138,7 +141,8 @@ bool fromwire_wireaddr_internal(const u8 **cursor, size_t *max,
|
|||
addr->u.torservice.port = fromwire_u16(cursor, max);
|
||||
return *cursor != NULL;
|
||||
case ADDR_INTERNAL_WIREADDR:
|
||||
return fromwire_wireaddr(cursor, max, &addr->u.wireaddr);
|
||||
addr->u.wireaddr.is_websocket = fromwire_bool(cursor, max);
|
||||
return fromwire_wireaddr(cursor, max, &addr->u.wireaddr.wireaddr);
|
||||
case ADDR_INTERNAL_FORPROXY:
|
||||
fromwire_u8_array(cursor, max, (u8 *)addr->u.unresolved.name,
|
||||
sizeof(addr->u.unresolved.name));
|
||||
|
@ -220,9 +224,13 @@ char *fmt_wireaddr_internal(const tal_t *ctx,
|
|||
case ADDR_INTERNAL_SOCKNAME:
|
||||
return tal_fmt(ctx, "%s", a->u.sockname);
|
||||
case ADDR_INTERNAL_ALLPROTO:
|
||||
return tal_fmt(ctx, ":%u", a->u.port);
|
||||
return tal_fmt(ctx, "%s:%u", a->u.allproto.is_websocket ? "(ws)": "",
|
||||
a->u.allproto.port);
|
||||
case ADDR_INTERNAL_WIREADDR:
|
||||
return fmt_wireaddr(ctx, &a->u.wireaddr);
|
||||
if (a->u.wireaddr.is_websocket)
|
||||
return tal_fmt(ctx, "(ws)%s",
|
||||
fmt_wireaddr(tmpctx, &a->u.wireaddr.wireaddr));
|
||||
return fmt_wireaddr(ctx, &a->u.wireaddr.wireaddr);
|
||||
case ADDR_INTERNAL_FORPROXY:
|
||||
return tal_fmt(ctx, "%s:%u",
|
||||
a->u.unresolved.name, a->u.unresolved.port);
|
||||
|
@ -573,7 +581,8 @@ bool wireaddr_internal_eq(const struct wireaddr_internal *a,
|
|||
case ADDR_INTERNAL_SOCKNAME:
|
||||
return streq(a->u.sockname, b->u.sockname);
|
||||
case ADDR_INTERNAL_ALLPROTO:
|
||||
return a->u.port == b->u.port;
|
||||
return a->u.allproto.is_websocket == b->u.allproto.is_websocket
|
||||
&& a->u.allproto.port == b->u.allproto.port;
|
||||
case ADDR_INTERNAL_STATICTOR:
|
||||
if (!memeq(a->u.torservice.blob, sizeof(a->u.torservice.blob),
|
||||
b->u.torservice.blob, sizeof(b->u.torservice.blob)))
|
||||
|
@ -589,7 +598,8 @@ bool wireaddr_internal_eq(const struct wireaddr_internal *a,
|
|||
return false;
|
||||
return a->u.unresolved.port == b->u.unresolved.port;
|
||||
case ADDR_INTERNAL_WIREADDR:
|
||||
return wireaddr_eq(&a->u.wireaddr, &b->u.wireaddr);
|
||||
return a->u.wireaddr.is_websocket == b->u.wireaddr.is_websocket
|
||||
&& wireaddr_eq(&a->u.wireaddr.wireaddr, &b->u.wireaddr.wireaddr);
|
||||
}
|
||||
abort();
|
||||
}
|
||||
|
@ -696,16 +706,18 @@ 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.port = splitport;
|
||||
addr->u.allproto.is_websocket = false;
|
||||
addr->u.allproto.port = splitport;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
needed_dns = false;
|
||||
err = parse_wireaddr(ctx, arg, default_port,
|
||||
dns_lookup_ok ? NULL : &needed_dns,
|
||||
&addr->u.wireaddr);
|
||||
&addr->u.wireaddr.wireaddr);
|
||||
if (!err) {
|
||||
addr->itype = ADDR_INTERNAL_WIREADDR;
|
||||
addr->u.wireaddr.is_websocket = false;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -779,7 +791,7 @@ struct addrinfo *wireaddr_internal_to_addrinfo(const tal_t *ctx,
|
|||
case ADDR_INTERNAL_FORPROXY:
|
||||
break;
|
||||
case ADDR_INTERNAL_WIREADDR:
|
||||
return wireaddr_to_addrinfo(ctx, &wireaddr->u.wireaddr);
|
||||
return wireaddr_to_addrinfo(ctx, &wireaddr->u.wireaddr.wireaddr);
|
||||
}
|
||||
abort();
|
||||
}
|
||||
|
@ -859,7 +871,7 @@ bool all_tor_addresses(const struct wireaddr_internal *wireaddr)
|
|||
case ADDR_INTERNAL_STATICTOR:
|
||||
continue;
|
||||
case ADDR_INTERNAL_WIREADDR:
|
||||
switch (wireaddr[i].u.wireaddr.type) {
|
||||
switch (wireaddr[i].u.wireaddr.wireaddr.type) {
|
||||
case ADDR_TYPE_IPV4:
|
||||
case ADDR_TYPE_IPV6:
|
||||
case ADDR_TYPE_DNS:
|
||||
|
|
|
@ -127,9 +127,15 @@ struct wireaddr_internal {
|
|||
enum wireaddr_internal_type itype;
|
||||
union {
|
||||
/* ADDR_INTERNAL_WIREADDR */
|
||||
struct wireaddr wireaddr;
|
||||
struct waddr {
|
||||
struct wireaddr wireaddr;
|
||||
bool is_websocket;
|
||||
} wireaddr;
|
||||
/* ADDR_INTERNAL_ALLPROTO */
|
||||
u16 port;
|
||||
struct allproto {
|
||||
u16 port;
|
||||
bool is_websocket;
|
||||
} allproto;
|
||||
/* ADDR_INTERNAL_AUTOTOR
|
||||
* ADDR_INTERNAL_STATICTOR */
|
||||
struct torservice {
|
||||
|
|
|
@ -410,12 +410,12 @@ static bool get_remote_address(struct io_conn *conn,
|
|||
if (s.ss_family == AF_INET6) {
|
||||
struct sockaddr_in6 *s6 = (void *)&s;
|
||||
addr->itype = ADDR_INTERNAL_WIREADDR;
|
||||
wireaddr_from_ipv6(&addr->u.wireaddr,
|
||||
wireaddr_from_ipv6(&addr->u.wireaddr.wireaddr,
|
||||
&s6->sin6_addr, ntohs(s6->sin6_port));
|
||||
} else if (s.ss_family == AF_INET) {
|
||||
struct sockaddr_in *s4 = (void *)&s;
|
||||
addr->itype = ADDR_INTERNAL_WIREADDR;
|
||||
wireaddr_from_ipv4(&addr->u.wireaddr,
|
||||
wireaddr_from_ipv4(&addr->u.wireaddr.wireaddr,
|
||||
&s4->sin_addr, ntohs(s4->sin_port));
|
||||
} else if (s.ss_family == AF_UNIX) {
|
||||
struct sockaddr_un *sun = (void *)&s;
|
||||
|
@ -468,6 +468,7 @@ static struct io_plan *connection_in(struct io_conn *conn,
|
|||
{
|
||||
struct conn_in conn_in_arg;
|
||||
|
||||
conn_in_arg.addr.u.wireaddr.is_websocket = false;
|
||||
if (!get_remote_address(conn, &conn_in_arg.addr))
|
||||
return io_close(conn);
|
||||
|
||||
|
@ -487,6 +488,7 @@ static struct io_plan *websocket_connection_in(struct io_conn *conn,
|
|||
int err;
|
||||
struct conn_in conn_in_arg;
|
||||
|
||||
conn_in_arg.addr.u.wireaddr.is_websocket = true;
|
||||
if (!get_remote_address(conn, &conn_in_arg.addr))
|
||||
return io_close(conn);
|
||||
|
||||
|
@ -724,10 +726,10 @@ static struct io_plan *conn_init(struct io_conn *conn,
|
|||
break;
|
||||
case ADDR_INTERNAL_WIREADDR:
|
||||
/* DNS should have been resolved before */
|
||||
assert(addr->u.wireaddr.type != ADDR_TYPE_DNS);
|
||||
assert(addr->u.wireaddr.wireaddr.type != ADDR_TYPE_DNS);
|
||||
/* If it was a Tor address, we wouldn't be here. */
|
||||
assert(!is_toraddr((char*)addr->u.wireaddr.addr));
|
||||
ai = wireaddr_to_addrinfo(tmpctx, &addr->u.wireaddr);
|
||||
assert(!is_toraddr((char*)addr->u.wireaddr.wireaddr.addr));
|
||||
ai = wireaddr_to_addrinfo(tmpctx, &addr->u.wireaddr.wireaddr);
|
||||
break;
|
||||
}
|
||||
assert(ai);
|
||||
|
@ -751,8 +753,8 @@ static struct io_plan *conn_proxy_init(struct io_conn *conn,
|
|||
port = addr->u.unresolved.port;
|
||||
break;
|
||||
case ADDR_INTERNAL_WIREADDR:
|
||||
host = fmt_wireaddr_without_port(tmpctx, &addr->u.wireaddr);
|
||||
port = addr->u.wireaddr.port;
|
||||
host = fmt_wireaddr_without_port(tmpctx, &addr->u.wireaddr.wireaddr);
|
||||
port = addr->u.wireaddr.wireaddr.port;
|
||||
break;
|
||||
case ADDR_INTERNAL_SOCKNAME:
|
||||
case ADDR_INTERNAL_ALLPROTO:
|
||||
|
@ -818,7 +820,7 @@ static void try_connect_one_addr(struct connecting *connect)
|
|||
use_proxy = true;
|
||||
break;
|
||||
case ADDR_INTERNAL_WIREADDR:
|
||||
switch (addr->u.wireaddr.type) {
|
||||
switch (addr->u.wireaddr.wireaddr.type) {
|
||||
case ADDR_TYPE_TOR_V2_REMOVED:
|
||||
af = -1;
|
||||
break;
|
||||
|
@ -848,9 +850,9 @@ static void try_connect_one_addr(struct connecting *connect)
|
|||
hints.ai_family = AF_UNSPEC;
|
||||
hints.ai_protocol = 0;
|
||||
hints.ai_flags = AI_ADDRCONFIG;
|
||||
gai_err = getaddrinfo((char *)addr->u.wireaddr.addr,
|
||||
gai_err = getaddrinfo((char *)addr->u.wireaddr.wireaddr.addr,
|
||||
tal_fmt(tmpctx, "%d",
|
||||
addr->u.wireaddr.port),
|
||||
addr->u.wireaddr.wireaddr.port),
|
||||
&hints, &ais);
|
||||
if (gai_err != 0) {
|
||||
tal_append_fmt(&connect->errors,
|
||||
|
@ -864,16 +866,17 @@ static void try_connect_one_addr(struct connecting *connect)
|
|||
/* create new addrhints on-the-fly per result ... */
|
||||
for (aii = ais; aii; aii = aii->ai_next) {
|
||||
addrhint.itype = ADDR_INTERNAL_WIREADDR;
|
||||
addrhint.u.wireaddr.is_websocket = false;
|
||||
if (aii->ai_family == AF_INET) {
|
||||
sa4 = (struct sockaddr_in *) aii->ai_addr;
|
||||
wireaddr_from_ipv4(&addrhint.u.wireaddr,
|
||||
wireaddr_from_ipv4(&addrhint.u.wireaddr.wireaddr,
|
||||
&sa4->sin_addr,
|
||||
addr->u.wireaddr.port);
|
||||
addr->u.wireaddr.wireaddr.port);
|
||||
} else if (aii->ai_family == AF_INET6) {
|
||||
sa6 = (struct sockaddr_in6 *) aii->ai_addr;
|
||||
wireaddr_from_ipv6(&addrhint.u.wireaddr,
|
||||
wireaddr_from_ipv6(&addrhint.u.wireaddr.wireaddr,
|
||||
&sa6->sin6_addr,
|
||||
addr->u.wireaddr.port);
|
||||
addr->u.wireaddr.wireaddr.port);
|
||||
} else {
|
||||
/* skip unsupported ai_family */
|
||||
continue;
|
||||
|
@ -1038,15 +1041,15 @@ fail:
|
|||
static struct listen_fd *handle_wireaddr_listen(const tal_t *ctx,
|
||||
const struct wireaddr_internal *wi,
|
||||
bool listen_mayfail,
|
||||
enum is_websocket is_websocket,
|
||||
char **errstr)
|
||||
{
|
||||
struct sockaddr_in addr;
|
||||
struct sockaddr_in6 addr6;
|
||||
const struct wireaddr *wireaddr;
|
||||
bool is_websocket = wi->u.wireaddr.is_websocket;
|
||||
|
||||
assert(wi->itype == ADDR_INTERNAL_WIREADDR);
|
||||
wireaddr = &wi->u.wireaddr;
|
||||
wireaddr = &wi->u.wireaddr.wireaddr;
|
||||
|
||||
/* Note the use of a switch() over enum here, even though it must be
|
||||
* IPv4 or IPv6 here; that will catch future changes. */
|
||||
|
@ -1098,10 +1101,12 @@ find_local_address(const struct listen_fd **listen_fds)
|
|||
for (size_t i = 0; i < tal_count(listen_fds); i++) {
|
||||
if (listen_fds[i]->wi.itype != ADDR_INTERNAL_WIREADDR)
|
||||
continue;
|
||||
if (listen_fds[i]->wi.u.wireaddr.type != ADDR_TYPE_IPV4
|
||||
&& listen_fds[i]->wi.u.wireaddr.type != ADDR_TYPE_IPV6)
|
||||
if (listen_fds[i]->wi.u.wireaddr.is_websocket)
|
||||
continue;
|
||||
return &listen_fds[i]->wi.u.wireaddr;
|
||||
if (listen_fds[i]->wi.u.wireaddr.wireaddr.type != ADDR_TYPE_IPV4
|
||||
&& listen_fds[i]->wi.u.wireaddr.wireaddr.type != ADDR_TYPE_IPV6)
|
||||
continue;
|
||||
return &listen_fds[i]->wi.u.wireaddr.wireaddr;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
@ -1164,7 +1169,7 @@ setup_listeners(const tal_t *ctx,
|
|||
/* You can only announce wiretypes, not internal formats! */
|
||||
assert(proposed_wireaddr[i].itype
|
||||
== ADDR_INTERNAL_WIREADDR);
|
||||
add_announceable(announceable, &wa.u.wireaddr);
|
||||
add_announceable(announceable, &wa.u.wireaddr.wireaddr);
|
||||
}
|
||||
|
||||
/* Now look for listening addresses. */
|
||||
|
@ -1204,42 +1209,41 @@ setup_listeners(const tal_t *ctx,
|
|||
bool ipv6_ok;
|
||||
|
||||
wa.itype = ADDR_INTERNAL_WIREADDR;
|
||||
wa.u.wireaddr.port = wa.u.port;
|
||||
wa.u.wireaddr.wireaddr.port = wa.u.allproto.port;
|
||||
wa.u.wireaddr.is_websocket = wa.u.allproto.is_websocket;
|
||||
|
||||
/* First, create wildcard IPv6 address. */
|
||||
wa.u.wireaddr.type = ADDR_TYPE_IPV6;
|
||||
wa.u.wireaddr.addrlen = 16;
|
||||
memset(wa.u.wireaddr.addr, 0,
|
||||
sizeof(wa.u.wireaddr.addr));
|
||||
wa.u.wireaddr.wireaddr.type = ADDR_TYPE_IPV6;
|
||||
wa.u.wireaddr.wireaddr.addrlen = 16;
|
||||
memset(wa.u.wireaddr.wireaddr.addr, 0,
|
||||
sizeof(wa.u.wireaddr.wireaddr.addr));
|
||||
|
||||
/* This may fail due to no IPv6 support. */
|
||||
lfd = handle_wireaddr_listen(ctx, &wa, false,
|
||||
NORMAL_SOCKET, errstr);
|
||||
lfd = handle_wireaddr_listen(ctx, &wa, false, errstr);
|
||||
if (lfd) {
|
||||
tal_arr_expand(&listen_fds,
|
||||
tal_steal(listen_fds, lfd));
|
||||
if (announce
|
||||
&& public_address(daemon, &wa.u.wireaddr))
|
||||
&& public_address(daemon, &wa.u.wireaddr.wireaddr))
|
||||
add_announceable(announceable,
|
||||
&wa.u.wireaddr);
|
||||
&wa.u.wireaddr.wireaddr);
|
||||
}
|
||||
ipv6_ok = (lfd != NULL);
|
||||
|
||||
/* Now, create wildcard IPv4 address. */
|
||||
wa.u.wireaddr.type = ADDR_TYPE_IPV4;
|
||||
wa.u.wireaddr.addrlen = 4;
|
||||
memset(wa.u.wireaddr.addr, 0,
|
||||
sizeof(wa.u.wireaddr.addr));
|
||||
wa.u.wireaddr.wireaddr.type = ADDR_TYPE_IPV4;
|
||||
wa.u.wireaddr.wireaddr.addrlen = 4;
|
||||
memset(wa.u.wireaddr.wireaddr.addr, 0,
|
||||
sizeof(wa.u.wireaddr.wireaddr.addr));
|
||||
/* This listen *may* fail, as long as IPv6 succeeds! */
|
||||
lfd = handle_wireaddr_listen(ctx, &wa, ipv6_ok,
|
||||
NORMAL_SOCKET, errstr);
|
||||
lfd = handle_wireaddr_listen(ctx, &wa, ipv6_ok, errstr);
|
||||
if (lfd) {
|
||||
tal_arr_expand(&listen_fds,
|
||||
tal_steal(listen_fds, lfd));
|
||||
if (announce
|
||||
&& public_address(daemon, &wa.u.wireaddr))
|
||||
&& public_address(daemon, &wa.u.wireaddr.wireaddr))
|
||||
add_announceable(announceable,
|
||||
&wa.u.wireaddr);
|
||||
&wa.u.wireaddr.wireaddr);
|
||||
} else if (!ipv6_ok) {
|
||||
/* Both failed, return now, errstr set. */
|
||||
return NULL;
|
||||
|
@ -1248,13 +1252,12 @@ setup_listeners(const tal_t *ctx,
|
|||
}
|
||||
/* This is a vanilla wireaddr as per BOLT #7 */
|
||||
case ADDR_INTERNAL_WIREADDR:
|
||||
lfd = handle_wireaddr_listen(ctx, &wa, false,
|
||||
NORMAL_SOCKET, errstr);
|
||||
lfd = handle_wireaddr_listen(ctx, &wa, false, errstr);
|
||||
if (!lfd)
|
||||
return NULL;
|
||||
tal_arr_expand(&listen_fds, tal_steal(listen_fds, lfd));
|
||||
if (announce && public_address(daemon, &wa.u.wireaddr))
|
||||
add_announceable(announceable, &wa.u.wireaddr);
|
||||
if (announce && public_address(daemon, &wa.u.wireaddr.wireaddr))
|
||||
add_announceable(announceable, &wa.u.wireaddr.wireaddr);
|
||||
continue;
|
||||
case ADDR_INTERNAL_FORPROXY:
|
||||
break;
|
||||
|
@ -1288,14 +1291,14 @@ setup_listeners(const tal_t *ctx,
|
|||
|
||||
/* Override with websocket port */
|
||||
addr = listen_fds[i]->wi;
|
||||
addr.u.wireaddr.port = daemon->websocket_port;
|
||||
addr.u.wireaddr.is_websocket = true;
|
||||
addr.u.wireaddr.wireaddr.port = daemon->websocket_port;
|
||||
|
||||
/* We set mayfail on all but the first websocket;
|
||||
* it's quite common to have multple overlapping
|
||||
* addresses. */
|
||||
lfd = handle_wireaddr_listen(ctx, &addr,
|
||||
announced_some,
|
||||
WEBSOCKET, errstr);
|
||||
lfd = handle_wireaddr_listen(ctx, &addr, announced_some,
|
||||
errstr);
|
||||
if (!lfd)
|
||||
continue;
|
||||
|
||||
|
@ -1610,10 +1613,11 @@ static void add_seed_addrs(struct wireaddr_internal **addrs,
|
|||
continue;
|
||||
struct wireaddr_internal a;
|
||||
a.itype = ADDR_INTERNAL_WIREADDR;
|
||||
a.u.wireaddr = new_addrs[j];
|
||||
a.u.wireaddr.is_websocket = false;
|
||||
a.u.wireaddr.wireaddr = new_addrs[j];
|
||||
status_peer_debug(id, "Resolved %s to %s", hostnames[i],
|
||||
type_to_string(tmpctx, struct wireaddr,
|
||||
&a.u.wireaddr));
|
||||
&a.u.wireaddr.wireaddr));
|
||||
tal_arr_expand(addrs, a);
|
||||
}
|
||||
/* Other seeds will likely have the same information. */
|
||||
|
@ -1640,7 +1644,8 @@ static void add_gossip_addrs_bytypes(struct wireaddr_internal **addrs,
|
|||
if (((u64)1 << normal_addrs[i].type) & types) {
|
||||
struct wireaddr_internal addr;
|
||||
addr.itype = ADDR_INTERNAL_WIREADDR;
|
||||
addr.u.wireaddr = normal_addrs[i];
|
||||
addr.u.wireaddr.is_websocket = false;
|
||||
addr.u.wireaddr.wireaddr = normal_addrs[i];
|
||||
tal_arr_expand(addrs, addr);
|
||||
}
|
||||
}
|
||||
|
@ -1731,8 +1736,10 @@ static void try_connect_peer(struct daemon *daemon,
|
|||
|
||||
/* Tell it to omit the existing hint (if that's a wireaddr itself) */
|
||||
add_gossip_addrs(&addrs, gossip_addrs,
|
||||
addrhint && addrhint->itype == ADDR_INTERNAL_WIREADDR
|
||||
? &addrhint->u.wireaddr : NULL);
|
||||
addrhint
|
||||
&& addrhint->itype == ADDR_INTERNAL_WIREADDR
|
||||
&& !addrhint->u.wireaddr.is_websocket
|
||||
? &addrhint->u.wireaddr.wireaddr : NULL);
|
||||
|
||||
if (tal_count(addrs) == 0) {
|
||||
/* Don't resolve via DNS seed if we're supposed to use proxy. */
|
||||
|
|
|
@ -236,13 +236,15 @@ struct io_plan *peer_exchange_initmsg(struct io_conn *conn,
|
|||
* incoming connection, if the node is the receiver and the connection was done
|
||||
* via IP.
|
||||
*/
|
||||
if (incoming && addr->itype == ADDR_INTERNAL_WIREADDR &&
|
||||
address_routable(&addr->u.wireaddr, true)) {
|
||||
switch (addr->u.wireaddr.type) {
|
||||
if (incoming
|
||||
&& addr->itype == ADDR_INTERNAL_WIREADDR
|
||||
&& !addr->u.wireaddr.is_websocket
|
||||
&& address_routable(&addr->u.wireaddr.wireaddr, true)) {
|
||||
switch (addr->u.wireaddr.wireaddr.type) {
|
||||
case ADDR_TYPE_IPV4:
|
||||
case ADDR_TYPE_IPV6:
|
||||
tlvs->remote_addr = tal_arr(tlvs, u8, 0);
|
||||
towire_wireaddr(&tlvs->remote_addr, &addr->u.wireaddr);
|
||||
towire_wireaddr(&tlvs->remote_addr, &addr->u.wireaddr.wireaddr);
|
||||
break;
|
||||
/* Only report IP addresses back for now */
|
||||
case ADDR_TYPE_TOR_V2_REMOVED:
|
||||
|
|
|
@ -327,7 +327,7 @@ int main(int argc, char *argv[])
|
|||
e_pub = pubkey("036360e856310ce5d294e8be33fc807077dc56ac80d95d9cd4ddbd21325eff73f7");
|
||||
|
||||
dummy.itype = ADDR_INTERNAL_WIREADDR;
|
||||
dummy.u.wireaddr.addrlen = 0;
|
||||
dummy.u.wireaddr.wireaddr.addrlen = 0;
|
||||
initiator_handshake((void *)tmpctx, &ls_pub, &rs_pub, &dummy, NULL, NORMAL_SOCKET, success, NULL);
|
||||
/* Should not exit! */
|
||||
abort();
|
||||
|
|
|
@ -321,7 +321,7 @@ int main(int argc, char *argv[])
|
|||
e_pub = pubkey("02466d7fcae563e5cb09a0d1870bb580344804617879a14949cf22285f1bae3f27");
|
||||
|
||||
dummy.itype = ADDR_INTERNAL_WIREADDR;
|
||||
dummy.u.wireaddr.addrlen = 0;
|
||||
dummy.u.wireaddr.wireaddr.addrlen = 0;
|
||||
responder_handshake((void *)tmpctx, &ls_pub, &dummy, NULL, NORMAL_SOCKET, success, NULL);
|
||||
/* Should not exit! */
|
||||
abort();
|
||||
|
|
|
@ -342,7 +342,10 @@ int main(int argc, char *argv[])
|
|||
opt_usage_exit_fail("Don't support proxy use");
|
||||
|
||||
case ADDR_INTERNAL_WIREADDR:
|
||||
switch (addr.u.wireaddr.type) {
|
||||
if (addr.u.wireaddr.is_websocket)
|
||||
opt_usage_exit_fail("Don't support websocket use");
|
||||
|
||||
switch (addr.u.wireaddr.wireaddr.type) {
|
||||
case ADDR_TYPE_TOR_V2_REMOVED:
|
||||
case ADDR_TYPE_TOR_V3:
|
||||
opt_usage_exit_fail("Don't support proxy use");
|
||||
|
@ -357,7 +360,7 @@ int main(int argc, char *argv[])
|
|||
af = AF_INET6;
|
||||
break;
|
||||
}
|
||||
ai = wireaddr_to_addrinfo(tmpctx, &addr.u.wireaddr);
|
||||
ai = wireaddr_to_addrinfo(tmpctx, &addr.u.wireaddr.wireaddr);
|
||||
}
|
||||
|
||||
if (af == -1 || ai == NULL)
|
||||
|
|
|
@ -53,10 +53,17 @@ On success, an object is returned, containing:
|
|||
- **channel** (hex): negotiated channel features we (as channel initiator) publish in the channel\_announcement message
|
||||
- **invoice** (hex): features in our BOLT11 invoices
|
||||
- **binding** (array of objects, optional): The addresses we are listening on:
|
||||
- **type** (string): Type of connection (one of "local socket", "ipv4", "ipv6", "torv2", "torv3")
|
||||
- **type** (string): Type of connection (one of "local socket", "websocket", "ipv4", "ipv6", "torv2", "torv3")
|
||||
- **address** (string, optional): address in expected format for **type**
|
||||
- **port** (u16, optional): port number
|
||||
- **socket** (string, optional): socket filename (only if **type** is "local socket")
|
||||
|
||||
If **type** is "local socket":
|
||||
|
||||
- **socket** (string): socket filename
|
||||
|
||||
If **type** is "websocket":
|
||||
|
||||
- **subtype** (string): type of address
|
||||
|
||||
The following warnings may also be returned:
|
||||
|
||||
|
@ -132,4 +139,4 @@ RESOURCES
|
|||
|
||||
Main web site: <https://github.com/ElementsProject/lightning>
|
||||
|
||||
[comment]: # ( SHA256STAMP:60310adb57a49cb425a4b0d424f176a0ffa4de312ed07855b5e5611a44a64fcf)
|
||||
[comment]: # ( SHA256STAMP:0e6f06ba4f0f0264614d93d4eb7abc38eeb13c9619f7bd4e21203cdaba363a02)
|
||||
|
|
|
@ -100,4 +100,4 @@ RESOURCES
|
|||
|
||||
Main web site: <https://github.com/ElementsProject/lightning>
|
||||
|
||||
[comment]: # ( SHA256STAMP:f7177be7c118fecf2e701d45140ad2714a42b746871caa8cd89e42bdc466d21c)
|
||||
[comment]: # ( SHA256STAMP:d74d92ee8839258837055e65823f74cae9775cf1c111565366c034c62e1c3021)
|
||||
|
|
|
@ -176,13 +176,13 @@
|
|||
"required": [
|
||||
"type"
|
||||
],
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"type": {
|
||||
"type": "string",
|
||||
"*FIXME*": "The variant in connect.schema.json is more complete",
|
||||
"enum": [
|
||||
"local socket",
|
||||
"websocket",
|
||||
"ipv4",
|
||||
"ipv6",
|
||||
"torv2",
|
||||
|
@ -197,12 +197,92 @@
|
|||
"port": {
|
||||
"type": "u16",
|
||||
"description": "port number"
|
||||
},
|
||||
"socket": {
|
||||
"type": "string",
|
||||
"description": "socket filename (only if **type** is \"local socket\")"
|
||||
}
|
||||
}
|
||||
},
|
||||
"allOf": [
|
||||
{
|
||||
"if": {
|
||||
"properties": {
|
||||
"type": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"local socket"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"then": {
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"type",
|
||||
"socket"
|
||||
],
|
||||
"properties": {
|
||||
"type": {},
|
||||
"socket": {
|
||||
"type": "string",
|
||||
"description": "socket filename"
|
||||
}
|
||||
}
|
||||
},
|
||||
"else": {
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"type",
|
||||
"address",
|
||||
"port"
|
||||
],
|
||||
"properties": {
|
||||
"type": {},
|
||||
"address": {},
|
||||
"port": {},
|
||||
"subtype": {}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"if": {
|
||||
"properties": {
|
||||
"type": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"websocket"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"then": {
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"type",
|
||||
"address",
|
||||
"port",
|
||||
"subtype"
|
||||
],
|
||||
"properties": {
|
||||
"type": {},
|
||||
"address": {},
|
||||
"port": {},
|
||||
"subtype": {
|
||||
"type": "string",
|
||||
"description": "type of address"
|
||||
}
|
||||
}
|
||||
},
|
||||
"else": {
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"type"
|
||||
],
|
||||
"properties": {
|
||||
"type": {},
|
||||
"address": {},
|
||||
"port": {},
|
||||
"socket": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"warning_bitcoind_sync": {
|
||||
|
|
|
@ -80,7 +80,7 @@
|
|||
"torv2",
|
||||
"torv3"
|
||||
],
|
||||
"description": "Type of connection (until 23.08, `websocket` was also allowed)"
|
||||
"description": "Type of connection (until 23.08, `websocket` was also allowed)"
|
||||
},
|
||||
"port": {
|
||||
"type": "u16",
|
||||
|
|
|
@ -417,7 +417,7 @@ struct channel *new_channel(struct peer *peer, u64 dbid,
|
|||
channel->scb = tal(channel, struct scb_chan);
|
||||
channel->scb->id = dbid;
|
||||
channel->scb->unused = 0;
|
||||
channel->scb->addr = peer->addr.u.wireaddr;
|
||||
channel->scb->addr = peer->addr.u.wireaddr.wireaddr;
|
||||
channel->scb->node_id = peer->id;
|
||||
channel->scb->funding = *funding;
|
||||
channel->scb->cid = *cid;
|
||||
|
|
|
@ -680,7 +680,8 @@ int connectd_init(struct lightningd *ld)
|
|||
wireaddrs = tal_arrz(tmpctx, struct wireaddr_internal, 1);
|
||||
listen_announce = tal_arr(tmpctx, enum addr_listen_announce, 1);
|
||||
wireaddrs->itype = ADDR_INTERNAL_ALLPROTO;
|
||||
wireaddrs->u.port = ld->portnum;
|
||||
wireaddrs->u.allproto.is_websocket = false;
|
||||
wireaddrs->u.allproto.port = ld->portnum;
|
||||
*listen_announce = ADDR_LISTEN_AND_ANNOUNCE;
|
||||
}
|
||||
|
||||
|
|
|
@ -1265,7 +1265,7 @@ wallet_commit_channel(struct lightningd *ld,
|
|||
channel->scb = tal(channel, struct scb_chan);
|
||||
channel->scb->id = channel->dbid;
|
||||
channel->scb->unused = 0;
|
||||
channel->scb->addr = channel->peer->addr.u.wireaddr;
|
||||
channel->scb->addr = channel->peer->addr.u.wireaddr.wireaddr;
|
||||
channel->scb->node_id = channel->peer->id;
|
||||
channel->scb->funding = *funding;
|
||||
channel->scb->cid = channel->cid;
|
||||
|
|
|
@ -1345,7 +1345,8 @@ static struct channel *stub_chan(struct command *cmd,
|
|||
struct wireaddr_internal wint;
|
||||
|
||||
wint.itype = ADDR_INTERNAL_WIREADDR;
|
||||
wint.u.wireaddr = addr;
|
||||
wint.u.wireaddr.is_websocket = false;
|
||||
wint.u.wireaddr.wireaddr = addr;
|
||||
peer = new_peer(cmd->ld,
|
||||
0,
|
||||
&nodeid,
|
||||
|
|
|
@ -231,7 +231,7 @@ static size_t num_announced_types(enum wire_addr_type type, struct lightningd *l
|
|||
for (size_t i = 0; i < tal_count(ld->proposed_wireaddr); i++) {
|
||||
if (ld->proposed_wireaddr[i].itype != ADDR_INTERNAL_WIREADDR)
|
||||
continue;
|
||||
if (ld->proposed_wireaddr[i].u.wireaddr.type != type)
|
||||
if (ld->proposed_wireaddr[i].u.wireaddr.wireaddr.type != type)
|
||||
continue;
|
||||
if (ld->proposed_listen_announce[i] & ADDR_ANNOUNCE)
|
||||
num++;
|
||||
|
@ -268,7 +268,7 @@ static char *opt_add_addr_withtype(const char *arg,
|
|||
/* Check they didn't specify some weird type! */
|
||||
switch (wi.itype) {
|
||||
case ADDR_INTERNAL_WIREADDR:
|
||||
switch (wi.u.wireaddr.type) {
|
||||
switch (wi.u.wireaddr.wireaddr.type) {
|
||||
case ADDR_TYPE_IPV4:
|
||||
case ADDR_TYPE_IPV6:
|
||||
/* These can be either bind or announce */
|
||||
|
|
Loading…
Add table
Reference in a new issue