From b013b3ab0ccc8129da422127830637359bb328e3 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Fri, 15 Oct 2021 16:18:44 +1030 Subject: [PATCH] patch websocket-address-support.patch --- common/json_helpers.c | 3 +++ common/wireaddr.c | 24 ++++++++++++++++++ common/wireaddr.h | 9 ++++++- connectd/connectd.c | 42 ++++++++++++++++++++----------- connectd/netaddress.c | 1 + devtools/gossipwith.c | 3 +++ doc/lightning-getinfo.7.md | 8 +++--- doc/lightning-listnodes.7.md | 8 +++--- doc/schemas/getinfo.schema.json | 38 ++++++++++++++++++++++------ doc/schemas/listnodes.schema.json | 38 ++++++++++++++++++++++------ 10 files changed, 139 insertions(+), 35 deletions(-) diff --git a/common/json_helpers.c b/common/json_helpers.c index 0629b03e7..65308d7ba 100644 --- a/common/json_helpers.c +++ b/common/json_helpers.c @@ -281,6 +281,9 @@ void json_add_address(struct json_stream *response, const char *fieldname, 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_WEBSOCKET) { + json_add_string(response, "type", "websocket"); + json_add_num(response, "port", addr->port); } json_object_end(response); } diff --git a/common/wireaddr.c b/common/wireaddr.c index 514b0ba2a..6851df8f8 100644 --- a/common/wireaddr.c +++ b/common/wireaddr.c @@ -37,6 +37,9 @@ bool fromwire_wireaddr(const u8 **cursor, size_t *max, struct wireaddr *addr) case ADDR_TYPE_TOR_V3: addr->addrlen = TOR_V3_ADDRLEN; break; + case ADDR_TYPE_WEBSOCKET: + addr->addrlen = 0; + break; default: return false; } @@ -160,6 +163,14 @@ void wireaddr_from_ipv6(struct wireaddr *addr, memcpy(&addr->addr, ip6, addr->addrlen); } +void wireaddr_from_websocket(struct wireaddr *addr, const u16 port) +{ + addr->type = ADDR_TYPE_WEBSOCKET; + addr->addrlen = 0; + addr->port = port; + memset(addr->addr, 0, sizeof(addr->addr)); +} + bool wireaddr_to_ipv4(const struct wireaddr *addr, struct sockaddr_in *s4) { if (addr->type != ADDR_TYPE_IPV4) @@ -184,6 +195,14 @@ bool wireaddr_to_ipv6(const struct wireaddr *addr, struct sockaddr_in6 *s6) return true; } +bool wireaddr_to_websocket(const struct wireaddr *addr, u16 *port) +{ + if (addr->type != ADDR_TYPE_WEBSOCKET) + return false; + *port = addr->port; + return true; +} + bool wireaddr_is_wildcard(const struct wireaddr *addr) { switch (addr->type) { @@ -192,6 +211,7 @@ bool wireaddr_is_wildcard(const struct wireaddr *addr) return memeqzero(addr->addr, addr->addrlen); case ADDR_TYPE_TOR_V2: case ADDR_TYPE_TOR_V3: + case ADDR_TYPE_WEBSOCKET: return false; } abort(); @@ -239,6 +259,8 @@ char *fmt_wireaddr_without_port(const tal_t * ctx, const struct wireaddr *a) case ADDR_TYPE_TOR_V3: return tal_fmt(ctx, "%s.onion", b32_encode(tmpctx, a->addr, a->addrlen)); + case ADDR_TYPE_WEBSOCKET: + return tal_strdup(ctx, "websocket"); } hex = tal_hexstr(ctx, a->addr, a->addrlen); @@ -675,6 +697,7 @@ struct addrinfo *wireaddr_to_addrinfo(const tal_t *ctx, return ai; case ADDR_TYPE_TOR_V2: case ADDR_TYPE_TOR_V3: + case ADDR_TYPE_WEBSOCKET: break; } abort(); @@ -729,6 +752,7 @@ bool all_tor_addresses(const struct wireaddr_internal *wireaddr) return false; case ADDR_TYPE_TOR_V2: case ADDR_TYPE_TOR_V3: + case ADDR_TYPE_WEBSOCKET: continue; } } diff --git a/common/wireaddr.h b/common/wireaddr.h index 7ca73b46a..383bcb519 100644 --- a/common/wireaddr.h +++ b/common/wireaddr.h @@ -37,6 +37,10 @@ struct sockaddr_un; * where `checksum = sha3(".onion checksum" | pubkey || version)[:2]` */ +/* BOLT-websockets #7: + * * `5`: WebSocket port; data = `[2:port]` (length 2) + */ + #define TOR_V2_ADDRLEN 10 #define TOR_V3_ADDRLEN 35 #define LARGEST_ADDRLEN TOR_V3_ADDRLEN @@ -47,7 +51,8 @@ enum wire_addr_type { ADDR_TYPE_IPV4 = 1, ADDR_TYPE_IPV6 = 2, ADDR_TYPE_TOR_V2 = 3, - ADDR_TYPE_TOR_V3 = 4 + ADDR_TYPE_TOR_V3 = 4, + ADDR_TYPE_WEBSOCKET = 5, }; /* Structure now fit for tor support */ @@ -98,8 +103,10 @@ void wireaddr_from_ipv4(struct wireaddr *addr, void wireaddr_from_ipv6(struct wireaddr *addr, const struct in6_addr *ip6, const u16 port); +void wireaddr_from_websocket(struct wireaddr *addr, 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); +bool wireaddr_to_websocket(const struct wireaddr *addr, u16 *port); bool wireaddr_is_wildcard(const struct wireaddr *addr); diff --git a/connectd/connectd.c b/connectd/connectd.c index 3b5f33969..892a531fc 100644 --- a/connectd/connectd.c +++ b/connectd/connectd.c @@ -835,36 +835,41 @@ static void try_connect_one_addr(struct connecting *connect) case ADDR_TYPE_IPV6: af = AF_INET6; break; + case ADDR_TYPE_WEBSOCKET: + af = -1; + break; } } /* If we have to use proxy but we don't have one, we fail. */ if (use_proxy) { if (!connect->daemon->proxyaddr) { - status_debug("Need proxy"); - af = -1; - } else - af = connect->daemon->proxyaddr->ai_family; + tal_append_fmt(&connect->errors, + "%s: need a proxy. ", + type_to_string(tmpctx, + struct wireaddr_internal, + addr)); + goto next; + } + af = connect->daemon->proxyaddr->ai_family; } if (af == -1) { - fd = -1; - errno = EPROTONOSUPPORT; - } else - fd = socket(af, SOCK_STREAM, 0); + tal_append_fmt(&connect->errors, + "%s: not supported. ", + type_to_string(tmpctx, struct wireaddr_internal, + addr)); + goto next; + } - /* We might not have eg. IPv6 support, or it might be an onion addr - * and we have no proxy. */ + fd = socket(af, SOCK_STREAM, 0); if (fd < 0) { tal_append_fmt(&connect->errors, "%s: opening %i socket gave %s. ", type_to_string(tmpctx, struct wireaddr_internal, addr), af, strerror(errno)); - /* This causes very limited recursion. */ - connect->addrnum++; - try_connect_one_addr(connect); - return; + goto next; } /* This creates the new connection using our fd, with the initialization @@ -878,6 +883,13 @@ static void try_connect_one_addr(struct connecting *connect) * that frees connect. */ if (conn) connect->conn = conn; + + return; + +next: + /* This causes very limited recursion. */ + connect->addrnum++; + try_connect_one_addr(connect); } /*~ connectd is responsible for incoming connections, but it's the process of @@ -988,6 +1000,8 @@ static bool handle_wireaddr_listen(struct daemon *daemon, return true; } return false; + /* Handle specially by callers. */ + case ADDR_TYPE_WEBSOCKET: case ADDR_TYPE_TOR_V2: case ADDR_TYPE_TOR_V3: break; diff --git a/connectd/netaddress.c b/connectd/netaddress.c index 1acfa6375..ce55cfa39 100644 --- a/connectd/netaddress.c +++ b/connectd/netaddress.c @@ -258,6 +258,7 @@ bool guess_address(struct wireaddr *addr) } case ADDR_TYPE_TOR_V2: case ADDR_TYPE_TOR_V3: + case ADDR_TYPE_WEBSOCKET: status_broken("Cannot guess address type %u", addr->type); break; } diff --git a/devtools/gossipwith.c b/devtools/gossipwith.c index c110c7908..2bd0a4778 100644 --- a/devtools/gossipwith.c +++ b/devtools/gossipwith.c @@ -321,6 +321,9 @@ int main(int argc, char *argv[]) case ADDR_TYPE_TOR_V3: opt_usage_exit_fail("Don't support proxy use"); break; + case ADDR_TYPE_WEBSOCKET: + opt_usage_exit_fail("Don't support websockets"); + break; case ADDR_TYPE_IPV4: af = AF_INET; break; diff --git a/doc/lightning-getinfo.7.md b/doc/lightning-getinfo.7.md index 2ec0ba960..1d6bd5187 100644 --- a/doc/lightning-getinfo.7.md +++ b/doc/lightning-getinfo.7.md @@ -40,9 +40,11 @@ On success, an object is returned, containing: - **network** (string): represents the type of network on the node are working (e.g: `bitcoin`, `testnet`, or `regtest`) - **fees_collected_msat** (msat): Total routing fees collected by this node - **address** (array of objects, optional): The addresses we announce to the world: - - **type** (string): Type of connection (one of "ipv4", "ipv6", "torv2", "torv3") - - **address** (string): address in expected format for **type** + - **type** (string): Type of connection (one of "ipv4", "ipv6", "torv2", "torv3", "websocket") - **port** (u16): port number + + If **type** is "ipv4", "ipv6", "torv2" or "torv3": + - **address** (string): address in expected format for **type** - **binding** (array of objects, optional): The addresses we are listening on: - **type** (string): Type of connection (one of "local socket", "ipv4", "ipv6", "torv2", "torv3") - **address** (string, optional): address in expected format for **type** @@ -115,4 +117,4 @@ RESOURCES --------- Main web site: -[comment]: # ( SHA256STAMP:a41fb9bb8e6e61bec105ff250584ae019dda93d4f97bfff53bc86d57ab6e8607) +[comment]: # ( SHA256STAMP:50c41a77a5f440cc22e5df9e3748e4280cd4508469887382690c580f10bc5af4) diff --git a/doc/lightning-listnodes.7.md b/doc/lightning-listnodes.7.md index bc7f074f3..59208b5a9 100644 --- a/doc/lightning-listnodes.7.md +++ b/doc/lightning-listnodes.7.md @@ -36,10 +36,12 @@ If **last_timestamp** is present: - **color** (hex): The favorite RGB color this node advertized (always 6 characters) - **features** (hex): BOLT #9 features bitmap this node advertized - **addresses** (array of objects): The addresses this node advertized: - - **type** (string): Type of connection (one of "ipv4", "ipv6", "torv2", "torv3") - - **address** (string): address in expected format for *type* + - **type** (string): Type of connection (one of "ipv4", "ipv6", "torv2", "torv3", "websocket") - **port** (u16): port number + If **type** is "ipv4", "ipv6", "torv2" or "torv3": + - **address** (string): address in expected format for **type** + If **option_will_fund** is present: - **option_will_fund** (object): - **lease_fee_base_msat** (msat): the fixed fee for a lease (whole number of satoshis) @@ -93,4 +95,4 @@ RESOURCES --------- Main web site: -[comment]: # ( SHA256STAMP:158477348efb51a8cf71a595b3d76dde545ab6824958c8a32d4b3dbbbe2c8121) +[comment]: # ( SHA256STAMP:f9e1f4655b416c5e60279cf11a832bc4c652f503e48095dc3cf39deee5f0c769) diff --git a/doc/schemas/getinfo.schema.json b/doc/schemas/getinfo.schema.json index 3c964fee2..02e2c5b43 100644 --- a/doc/schemas/getinfo.schema.json +++ b/doc/schemas/getinfo.schema.json @@ -64,22 +64,46 @@ "description": "The addresses we announce to the world", "items": { "type": "object", - "required": [ "type", "address", "port" ], - "additionalProperties": false, + "required": [ "type", "port" ], + "additionalProperties": true, "properties": { "type": { "type": "string", - "enum": [ "ipv4", "ipv6", "torv2", "torv3" ], + "enum": [ "ipv4", "ipv6", "torv2", "torv3", "websocket" ], "description": "Type of connection" }, - "address": { - "type": "string", - "description": "address in expected format for **type**" - }, "port": { "type": "u16", "description": "port number" } + }, + "if": { + "properties": { + "type": { + "type": "string", + "enum": [ "ipv4", "ipv6", "torv2", "torv3" ] + } + } + }, + "then": { + "required": [ "type", "address", "port" ], + "additionalProperties": false, + "properties": { + "type": { }, + "port": { }, + "address": { + "type": "string", + "description": "address in expected format for **type**" + } + } + }, + "else": { + "required": [ "type", "port" ], + "additionalProperties": false, + "properties": { + "type": { }, + "port": { } + } } } }, diff --git a/doc/schemas/listnodes.schema.json b/doc/schemas/listnodes.schema.json index 1672bc485..4437bfbc8 100644 --- a/doc/schemas/listnodes.schema.json +++ b/doc/schemas/listnodes.schema.json @@ -52,22 +52,46 @@ "description": "The addresses this node advertized", "items": { "type": "object", - "required": [ "type", "address", "port" ], - "additionalProperties": false, + "required": [ "type", "port" ], + "additionalProperties": true, "properties": { "type": { "type": "string", - "enum": [ "ipv4", "ipv6", "torv2", "torv3" ], + "enum": [ "ipv4", "ipv6", "torv2", "torv3", "websocket" ], "description": "Type of connection" }, - "address": { - "type": "string", - "description": "address in expected format for *type*" - }, "port": { "type": "u16", "description": "port number" } + }, + "if": { + "properties": { + "type": { + "type": "string", + "enum": [ "ipv4", "ipv6", "torv2", "torv3" ] + } + } + }, + "then": { + "required": [ "type", "address", "port" ], + "additionalProperties": false, + "properties": { + "type": { }, + "port": { }, + "address": { + "type": "string", + "description": "address in expected format for **type**" + } + } + }, + "else": { + "required": [ "type", "port" ], + "additionalProperties": false, + "properties": { + "type": { }, + "port": { } + } } } }