connectd: gate uniform message padding behind --dev-uniform-padding
What changed, and why it matters
This change makes a message-padding privacy feature optional rather than always-on, because the always-on version was accidentally breaking connections to LND (another popular Lightning implementation). It is a compatibility/bug-fix commit, not a direct security patch, though it touches a feature that was intended to improve privacy against traffic analysis.
Treat as a compatibility bug fix, not a security vulnerability. Operators wanting traffic-analysis padding should explicitly enable --dev-uniform-padding and be aware it may disconnect from LND peers until LND fixes its BOLT #1 handling. No urgent patching required for security reasons.
Security signals we found
Privacy/traffic-analysis defense feature (uniform message padding) is made opt-in
Interoperability breakage with LND peers caused by BOLT #1 non-compliance in LND
No memory corruption, authentication bypass, or cryptographic weakness visible in diff
Change is defensive: reduces risk of accidental peer isolation but weakens default traffic-analysis resistance
Evidence from the diff
Core Lightning’s connectd previously padded every outgoing encrypted message to a uniform 1460-byte chunk. This caused LND peers to disconnect when receiving a ping(num_pong_bytes=65535) because LND rejects oversized pong requests instead of ignoring them per BOLT #1. The commit gates the uniform padding behavior behind a new –dev-uniform-padding flag, defaulting to off. When disabled, connectd flushes whatever encrypted data is available instead of padding to UNIFORM_MESSAGE_SIZE. The diff modifies connectd/multiplex.c: write_encrypted_to_peer now chooses write_size based on dev_uniform_padding, and write_to_peer only calls pad_encrypted_queue when the flag is set.
Changed components
connectd/multiplex.cOutgoing encrypted message queue handlingUniform message padding featureInspect captured patch +21 / −4
diff --git a/connectd/multiplex.c b/connectd/multiplex.c
index c219ba8d..8cfaa885 100644
--- a/connectd/multiplex.c
+++ b/connectd/multiplex.c
@@ -484,10 +484,16 @@ static bool have_empty_encrypted_queue(const struct peer *peer)
/* (Continue) writing the encrypted_peer_out array */
static struct io_plan *write_encrypted_to_peer(struct peer *peer)
{
- assert(membuf_num_elems(&peer->encrypted_peer_out) >= UNIFORM_MESSAGE_SIZE);
+ size_t avail = membuf_num_elems(&peer->encrypted_peer_out);
+ /* With padding: always a full uniform-size chunk.
+ * Without: flush whatever we have (caller ensures non-zero). */
+ size_t write_size = peer->daemon->dev_uniform_padding
+ ? UNIFORM_MESSAGE_SIZE : avail;
+
+ assert(avail >= write_size && write_size > 0);
return io_write_partial(peer->to_peer,
membuf_elems(&peer->encrypted_peer_out),
- UNIFORM_MESSAGE_SIZE,
+ write_size,
&peer->encrypted_peer_out_sent,
write_to_peer, peer);
}
@@ -1244,8 +1250,11 @@ static struct io_plan *write_to_peer(struct io_conn *peer_conn,
/* Wait for them to wake us */
return msg_queue_wait(peer_conn, peer->peer_outq, write_to_peer, peer);
}
- /* OK, add padding. */
- pad_encrypted_queue(peer);
+ /* OK, add padding (only if --dev-uniform-padding enabled). */
+ if (peer->daemon->dev_uniform_padding)
+ pad_encrypted_queue(peer);
+ else
+ break;
} else {
if (peer->draining_state == WRITING_TO_PEER)
status_peer_debug(&peer->id, "draining, but sending %s.",
@@ -1263,6 +1272,14 @@ static struct io_plan *write_to_peer(struct io_conn *peer_conn,
}
peer->nonurgent_flush_timer = tal_free(peer->nonurgent_flush_timer);
+
+ /* With uniform padding the buffer is always a full UNIFORM_MESSAGE_SIZE.
+ * Without it, write whatever we have; if nothing, go back to waiting. */
+ if (have_empty_encrypted_queue(peer)) {
+ io_wake(&peer->subds);
+ io_wake(&peer->peer_in);
+ return msg_queue_wait(peer_conn, peer->peer_outq, write_to_peer, peer);
+ }
return write_encrypted_to_peer(peer);
}
Why this scored 40/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.