connectd: keep their_features inside struct peer.
What changed, and why it matters
This is a small internal code cleanup in Core Lightning's connection handling. It moves a copy of the peer's feature list into the peer structure so it can be used later. There is no security fix or vulnerability visible in this change.
No security action required. Treat as normal refactoring.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The commit refactors connectd to store their_features as a tal-allocated member of struct peer rather than passing it around as a transient argument. The new_peer() signature is updated with TAKES ownership semantics, and peer_connected() now duplicates the features and frees the original when appropriate. Subsequent code reads from peer->their_features instead of the local parameter. This is preparatory refactoring with no behavioral security change evident from the diff.
Changed components
connectd/connectd.cconnectd/connectd.hInspect captured patch +14 / −9
diff --git a/connectd/connectd.c b/connectd/connectd.c
index 6685c471..1dbc660c 100644
--- a/connectd/connectd.c
+++ b/connectd/connectd.c
@@ -113,7 +113,7 @@ static void destroy_peer(struct peer *peer)
static struct peer *new_peer(struct daemon *daemon,
const struct node_id *id,
const struct crypto_state *cs,
- const u8 *their_features,
+ const u8 *their_features TAKES,
enum is_websocket is_websocket,
struct timemono connect_starttime,
struct io_conn *conn STEALS,
@@ -154,6 +154,7 @@ static struct peer *new_peer(struct daemon *daemon,
peer->onionmsg_incoming_tokens = ONION_MSG_TOKENS_MAX;
peer->onionmsg_last_incoming = time_mono();
peer->onionmsg_limit_warned = false;
+ peer->their_features = tal_dup_talarr(peer, u8, their_features);
peer->to_peer = conn;
@@ -320,10 +321,6 @@ struct io_plan *peer_connected(struct io_conn *conn,
destroy_peer_immediately(oldpeer);
}
- /* We promised we'd take it by marking it TAKEN above; prepare to free it. */
- if (taken(their_features))
- tal_steal(tmpctx, their_features);
-
/* BOLT #1:
*
* The receiving node:
@@ -336,6 +333,9 @@ struct io_plan *peer_connected(struct io_conn *conn,
unsup = features_unsupported(daemon->our_features, their_features,
INIT_FEATURE);
if (unsup != -1) {
+ if (taken(their_features))
+ tal_free(their_features);
+
/* We were going to send a reconnect message, but not now! */
if (oldpeer)
send_disconnected(daemon, id, prev_connectd_counter,
@@ -348,6 +348,9 @@ struct io_plan *peer_connected(struct io_conn *conn,
}
if (!feature_check_depends(their_features, &depender, &missing)) {
+ if (taken(their_features))
+ tal_free(their_features);
+
/* We were going to send a reconnect message, but not now! */
if (oldpeer)
send_disconnected(daemon, id, prev_connectd_counter,
@@ -407,11 +410,11 @@ struct io_plan *peer_connected(struct io_conn *conn,
/* Tell gossipd it can ask query this new peer for gossip */
option_gossip_queries = feature_negotiated(daemon->our_features,
- their_features,
+ peer->their_features,
OPT_GOSSIP_QUERIES);
/* Get ready for streaming gossip from the store */
- setup_peer_gossip_store(peer, daemon->our_features, their_features);
+ setup_peer_gossip_store(peer, daemon->our_features, peer->their_features);
/* Create message to tell master peer has connected/reconnected. */
if (oldpeer) {
@@ -419,7 +422,7 @@ struct io_plan *peer_connected(struct io_conn *conn,
prev_connectd_counter,
peer->counter,
addr, remote_addr,
- incoming, their_features,
+ incoming, peer->their_features,
time_to_nsec(timemono_since(prev_connect_start)));
} else {
/* Tell gossipd about new peer */
@@ -428,7 +431,7 @@ struct io_plan *peer_connected(struct io_conn *conn,
msg = towire_connectd_peer_connected(NULL, id, peer->counter,
addr, remote_addr,
- incoming, their_features,
+ incoming, peer->their_features,
connect_reason,
connect_time_nsec);
}
diff --git a/connectd/connectd.h b/connectd/connectd.h
index 25d25483..2ea40eef 100644
--- a/connectd/connectd.h
+++ b/connectd/connectd.h
@@ -67,6 +67,8 @@ struct peer {
struct crypto_state cs;
/* Time when we first connected */
struct timemono connect_starttime;
+ /* Features they told us about */
+ const u8 *their_features;
/* Connection to the peer (NULL if it's disconnected and we're flushing) */
struct io_conn *to_peer;
Why this scored 15/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.