Skip to content

Commit

Permalink
Changelog-Added: Introduce support for alternative addresses for peer…
Browse files Browse the repository at this point in the history
… connections

- Added new configuration parameters: alt-addr, alt-bind-addr, and alt-announce-addr.
- Enhanced peer connection handling to use alternative addresses for selective private communications.
- Added database fields to store alternative addresses for peers.
- Implemented new RPC commands managing alternative addresses.
- Updated tests to verify the behavior of alternative address handling in different scenarios.

Signed-off-by: Max Rantil <[email protected]>
  • Loading branch information
maxrantil committed Jul 5, 2024
1 parent 11586ab commit 821e28d
Show file tree
Hide file tree
Showing 36 changed files with 1,041 additions and 283 deletions.
17 changes: 17 additions & 0 deletions .msggen.json
Original file line number Diff line number Diff line change
Expand Up @@ -1589,6 +1589,7 @@
"ListConfigs.configs.addr": 47,
"ListConfigs.configs.alias": 30,
"ListConfigs.configs.allow-deprecated-apis": 14,
"ListConfigs.configs.alt-addr": 71,
"ListConfigs.configs.always-use-proxy": 17,
"ListConfigs.configs.announce-addr": 48,
"ListConfigs.configs.announce-addr-discovered": 54,
Expand Down Expand Up @@ -1672,6 +1673,10 @@
"ListConfigs.configs.allow-deprecated-apis.source": 2,
"ListConfigs.configs.allow-deprecated-apis.value_bool": 1
},
"ListconfigsConfigsAlt-addr": {
"ListConfigs.configs.alt-addr.sources[]": 2,
"ListConfigs.configs.alt-addr.values_str[]": 1
},
"ListconfigsConfigsAlways-use-proxy": {
"ListConfigs.configs.always-use-proxy.source": 2,
"ListConfigs.configs.always-use-proxy.value_bool": 1
Expand Down Expand Up @@ -6678,6 +6683,18 @@
"added": "pre-v0.10.1",
"deprecated": false
},
"ListConfigs.configs.alt-addr": {
"added": "v24.05",
"deprecated": false
},
"ListConfigs.configs.alt-addr.sources[]": {
"added": "v24.05",
"deprecated": false
},
"ListConfigs.configs.alt-addr.values_str[]": {
"added": "v24.05",
"deprecated": false
},
"ListConfigs.configs.always-use-proxy": {
"added": "pre-v0.10.1",
"deprecated": false
Expand Down
43 changes: 42 additions & 1 deletion channeld/channeld.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,9 @@ struct peer {
bool channel_ready[NUM_SIDES];
u64 next_index[NUM_SIDES];

/* ID of peer */
struct node_id id;

/* --developer? */
bool developer;

Expand Down Expand Up @@ -191,9 +194,13 @@ struct peer {

/* --experimental-upgrade-protocol */
bool experimental_upgrade;

/* Alt address for peer connections not publicly announced */
u8 *our_alt_addr;
};

static void start_commit_timer(struct peer *peer);
static void send_peer_our_alt_addr(struct peer *peer);

static void billboard_update(const struct peer *peer)
{
Expand Down Expand Up @@ -535,6 +542,16 @@ static void handle_peer_splice_locked(struct peer *peer, const u8 *msg)
check_mutual_splice_locked(peer);
}

static void send_peer_our_alt_addr(struct peer *peer)
{
struct pubkey node_id;

if (pubkey_from_node_id(&node_id, &peer->id)) {
u8 *msg = towire_peer_alt_addr(peer, &node_id, peer->our_alt_addr);
peer_write(peer->pps, take(msg));
}
}

static void handle_peer_channel_ready(struct peer *peer, const u8 *msg)
{
struct channel_id chanid;
Expand Down Expand Up @@ -4163,6 +4180,9 @@ static void peer_in(struct peer *peer, const u8 *msg)

check_tx_abort(peer, msg);

if (peer->our_alt_addr)
send_peer_our_alt_addr(peer);

/* If we're in STFU mode and aren't waiting for a STFU mode
* specific message, the only valid message was tx_abort */
if (is_stfu_active(peer) && !peer->stfu_wait_single_msg) {
Expand Down Expand Up @@ -4295,6 +4315,7 @@ static void peer_in(struct peer *peer, const u8 *msg)
case WIRE_ONION_MESSAGE:
case WIRE_PEER_STORAGE:
case WIRE_YOUR_PEER_STORAGE:
case WIRE_PEER_ALT_ADDR:
abort();
}

Expand Down Expand Up @@ -5682,11 +5703,29 @@ static void handle_dev_quiesce(struct peer *peer, const u8 *msg)
maybe_send_stfu(peer);
}

static void handle_channeld_alt_addr(struct peer *peer, const u8 *msg)
{
struct pubkey peer_pk;
u8 *our_alt_addr;

if (!fromwire_channeld_alt_addr(peer, msg, &peer_pk, &our_alt_addr)) {
master_badmsg(WIRE_CHANNELD_ALT_ADDR, msg);
}

if (pubkey_from_node_id(&peer_pk, &peer->id)) {
u8 *peer_msg = towire_peer_alt_addr(peer, &peer_pk, our_alt_addr);
peer_write(peer->pps, take(peer_msg));
}
}

static void req_in(struct peer *peer, const u8 *msg)
{
enum channeld_wire t = fromwire_peektype(msg);

switch (t) {
case WIRE_CHANNELD_ALT_ADDR:
handle_channeld_alt_addr(peer, msg);
return;
case WIRE_CHANNELD_FUNDING_DEPTH:
handle_funding_depth(peer, msg);
return;
Expand Down Expand Up @@ -5869,7 +5908,9 @@ static void init_channel(struct peer *peer)
&reestablish_only,
&peer->experimental_upgrade,
&peer->splice_state->inflights,
&peer->local_alias)) {
&peer->local_alias,
&peer->our_alt_addr,
&peer->id)) {
master_badmsg(WIRE_CHANNELD_INIT, msg);
}

Expand Down
9 changes: 9 additions & 0 deletions channeld/channeld_wire.csv
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,9 @@ msgdata,channeld_init,experimental_upgrade,bool,
msgdata,channeld_init,num_inflights,u16,
msgdata,channeld_init,inflights,inflight,num_inflights
msgdata,channeld_init,scid_alias,short_channel_id,
msgdata,channeld_init,alt_addr_len,u16,
msgdata,channeld_init,alt_addr,u8,alt_addr_len,
msgdata,channeld_init,id,node_id,

# channeld->lightningd: successfully negotated reestablishment.
msgtype,channeld_reestablished,1101
Expand Down Expand Up @@ -349,3 +352,9 @@ msgdata,channeld_upgraded,new_type,channel_type,
# Tell peer about our latest and greatest blockheight.
msgtype,channeld_blockheight,1012
msgdata,channeld_blockheight,blockheight,u32,

# master -> channeld Send peer alternative addresses
msgtype,channeld_alt_addr,1014
msgdata,channeld_alt_addr,node_id,point,
msgdata,channeld_alt_addr,alt_addr_len,u16,
msgdata,channeld_alt_addr,alt_addr,u8,alt_addr_len,
6 changes: 6 additions & 0 deletions cln-grpc/proto/node.proto

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 13 additions & 0 deletions cln-grpc/src/convert.rs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions cln-rpc/src/model.rs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions common/interactivetx.c
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,7 @@ static u8 *read_next_msg(const tal_t *ctx,
case WIRE_SPLICE:
case WIRE_SPLICE_ACK:
case WIRE_SPLICE_LOCKED:
case WIRE_PEER_ALT_ADDR:
*error = tal_fmt(ctx,
"Received invalid message from peer: %d", t);
return NULL;
Expand Down Expand Up @@ -736,6 +737,7 @@ char *process_interactivetx_updates(const tal_t *ctx,
case WIRE_SPLICE_ACK:
case WIRE_STFU:
case WIRE_SPLICE_LOCKED:
case WIRE_PEER_ALT_ADDR:
return tal_fmt(ctx, "Unexpected wire message %s",
tal_hex(ctx, msg));
}
Expand Down
83 changes: 82 additions & 1 deletion connectd/connectd.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <wire/peer_wiregen.h>
#include <wire/wire_io.h>
#include <wire/wire_sync.h>

Expand Down Expand Up @@ -316,6 +317,26 @@ static struct io_plan *handshake_in_success(struct io_conn *conn,
struct node_id id;
node_id_from_pubkey(&id, id_key);
status_peer_debug(&id, "Connect IN");

/* FIXME(maxrantil): loop all alt_bind_addr after making it an array (code down-under)*/
/* bool is_whitelisted = false;
if (daemon->alt_bind_addr) {
for (size_t i = 0; i < tal_count(daemon->alt_bind_addr); i++) {
if (strcmp(incoming_addr, (char *)daemon->alt_bind_addr[i]) == 0) {
is_whitelisted = true;
break;
}
}
} */

char *incoming_addr = fmt_wireaddr_internal(tmpctx, addr);

/* Confirm that peer connects to the alt-bind-addr you sent */
if (daemon->alt_bind_addr)
if (strcmp(incoming_addr, (char *)daemon->alt_bind_addr) == 0)
towire_connectd_alt_addr_whitelist(tmpctx, id_key, (u8 *)incoming_addr);

return peer_exchange_initmsg(conn, daemon, daemon->our_features,
cs, &id, addr, timeout, is_websocket, true);
}
Expand Down Expand Up @@ -505,9 +526,26 @@ static struct io_plan *connection_in(struct io_conn *conn,

conn_in_arg.daemon = daemon;
conn_in_arg.is_websocket = false;

return conn_in(conn, &conn_in_arg);
}

void handle_peer_alt_addr(struct peer *peer, const u8 *msg)
{
u8 *peer_alt_addr;
struct pubkey peer_id;
/* FIXME(maxrantil): u32 *timestamp = NULL; */

if (!fromwire_peer_alt_addr(peer, msg, &peer_id, &peer_alt_addr/* FIXME(maxrantil): , timestamp */)) {
master_badmsg(WIRE_PEER_ALT_ADDR, msg);
}

u8 *fwd_msg = towire_connectd_alt_addr(NULL, &peer_id, peer_alt_addr);
daemon_conn_send(peer->daemon->master, take(fwd_msg));

tal_free(peer_alt_addr); /* FIXME(maxrantil): Investigare further on freeing like this */
}

/*~ <hello>I speak web socket</hello>.
*
* Actually that's dumb, websocket (aka rfc6455) looks nothing like that. */
Expand Down Expand Up @@ -1413,7 +1451,8 @@ static void connect_init(struct daemon *daemon, const u8 *msg)
&daemon->dev_fast_gossip,
&dev_disconnect,
&daemon->dev_no_ping_timer,
&daemon->dev_handshake_no_reply)) {
&daemon->dev_handshake_no_reply,
&daemon->alt_bind_addr)) {
/* This is a helper which prints the type expected and the actual
* message, then exits (it should never be called!). */
master_badmsg(WIRE_CONNECTD_INIT, msg);
Expand Down Expand Up @@ -2059,6 +2098,41 @@ static void dev_exhaust_fds(struct daemon *daemon, const u8 *msg)
daemon->dev_exhausted_fds = true;
}

static void handle_alt_addr_whitelist_reply(struct daemon *daemon, const u8 *msg)
{
struct pubkey p_pk;
struct peer *peer;
u8 *incoming_addr;
bool is_whitelisted;

if (!fromwire_connectd_alt_addr_whitelist_reply(tmpctx,
msg, &p_pk, &incoming_addr, &is_whitelisted)) {
master_badmsg(WIRE_CONNECTD_ALT_ADDR_WHITELIST_REPLY, msg);
return;
}

struct node_id id;
node_id_from_pubkey(&id, &p_pk);
peer = peer_htable_get(daemon->peers, &id);

if (!peer) {
status_broken("handle_alt_addr_whitelist_reply: Could not find peer for node_id: %s",
fmt_node_id(tmpctx, &id));
return;
}

if (is_whitelisted) {
status_peer_unusual(&peer->id,
"Peer's address %s is in the whitelist. Accepting connection.",
incoming_addr);
} else {
status_peer_unusual(&peer->id,
"Connection attempt from address %s which is not in the whitelist. The peer has not received an alternative address from me. Closing connection.",
incoming_addr);
io_close(peer->to_peer);
}
}

static struct io_plan *recv_peer_connect_subd(struct io_conn *conn,
const u8 *msg,
int fd,
Expand Down Expand Up @@ -2145,6 +2219,11 @@ static struct io_plan *recv_req(struct io_conn *conn,
dev_exhaust_fds(daemon, msg);
goto out;
}
case WIRE_CONNECTD_ALT_ADDR_WHITELIST_REPLY:
if (daemon->developer) {
handle_alt_addr_whitelist_reply(daemon, msg);
goto out;
}
/* Fall thru */
/* We send these, we don't receive them */
case WIRE_CONNECTD_INIT_REPLY:
Expand All @@ -2158,6 +2237,8 @@ static struct io_plan *recv_req(struct io_conn *conn,
case WIRE_CONNECTD_CUSTOMMSG_IN:
case WIRE_CONNECTD_PEER_DISCONNECT_DONE:
case WIRE_CONNECTD_START_SHUTDOWN_REPLY:
case WIRE_CONNECTD_ALT_ADDR:
case WIRE_CONNECTD_ALT_ADDR_WHITELIST:
break;
}

Expand Down
Loading

0 comments on commit 821e28d

Please sign in to comment.