From ee5e65e8479a207b32659f3366a5c223d3f53181 Mon Sep 17 00:00:00 2001 From: junderw Date: Wed, 24 Jun 2026 20:11:27 +0900 Subject: [PATCH] fix: Do not discard leftover --- AGENTS.md | 19 +++++++++++++++++++ scripts/checks.sh | 8 +++++--- src/electrum/server.rs | 36 ++++++++++++++++++------------------ 3 files changed, 42 insertions(+), 21 deletions(-) create mode 100644 AGENTS.md diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..6599af6 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,19 @@ +# electrs + +## Rules + +1. You are an expert Rust developer. +2. You are an expert Bitcoin developer. +3. If you are unsure of a change, ask the developer to make a choice proactively. + +## Before testing + +- Run cargo fmt (from root) + - command: `cargo fmt` + +## Testing + +- Run the checks script + - `./scripts/checks.sh` +- Run with tests only when a test is added or changed + - `INCLUDE_TESTS=1 ./scripts/checks.sh` diff --git a/scripts/checks.sh b/scripts/checks.sh index a80db52..51aa98a 100755 --- a/scripts/checks.sh +++ b/scripts/checks.sh @@ -57,6 +57,8 @@ TESTNAME="Running cargo clippy check electrum-discovery + liquid" echo "$TESTNAME" cargo clippy $@ -q -F electrum-discovery,liquid -TESTNAME="Running cargo test with all features" -echo "$TESTNAME" -cargo test $@ -q --lib --all-features +if [ $INCLUDE_TESTS ]; then + TESTNAME="Running cargo test with all features" + echo "$TESTNAME" + cargo test $@ -q --lib --all-features +fi diff --git a/src/electrum/server.rs b/src/electrum/server.rs index fcd9988..1722db0 100644 --- a/src/electrum/server.rs +++ b/src/electrum/server.rs @@ -869,26 +869,27 @@ impl Connection { stream: ConnectionStream, tx: crossbeam_channel::Sender, max_line_size: usize, - parse_proxy: bool, ) -> Result<()> { let mut stream = stream; - // Parse any PROXY-protocol (HAProxy) headers at the very start of the - // connection before treating the stream as Electrum requests. The parsed - // addresses are forwarded over the channel so the connection can identify - // the client; any leftover bytes belong to the first Electrum request. + // Consume any PROXY-protocol (HAProxy) headers at the very start of the + // connection before treating the stream as Electrum requests. We always + // consume them — even when HAProxy support is disabled + // (`electrum-haproxy-depth = 0`) — so that PROXY headers sent by an + // accidentally-misconfigured upstream are stripped instead of corrupting + // the Electrum request parser. + // + // Crucially, `read_proxy_headers` only ever buffers bytes it has already + // read from the socket: when no PROXY header is present it returns those + // bytes as `leftover` so the start of the first Electrum request is + // preserved rather than discarded. + // + // The parsed addresses are forwarded over the channel; whether they are + // actually used to identify the client is decided later based on the + // configured `electrum-haproxy-depth` (a depth of 0 ignores them). let (proxy_addrs, leftover) = Connection::read_proxy_headers(&mut stream)?; - let leftover = if parse_proxy { - tx.send(Message::Proxy(proxy_addrs)) - .chain_err(|| "channel closed")?; - leftover - } else { - // If we're not configured to parse PROXY headers, just discard them and any - // bytes read while looking for them, to avoid confusing the Electrum request parser. - tx.send(Message::Proxy(None)) - .chain_err(|| "channel closed")?; - Vec::new() - }; + tx.send(Message::Proxy(proxy_addrs)) + .chain_err(|| "channel closed")?; let mut reader = BufReader::new(Cursor::new(leftover).chain(stream)); loop { @@ -948,9 +949,8 @@ impl Connection { }); let max_line_size = self.max_line_size; - let parse_proxy = self.haproxy_depth > 0; let child = spawn_thread("reader", move || { - Connection::handle_requests(stream, tx, max_line_size, parse_proxy) + Connection::handle_requests(stream, tx, max_line_size) }); if let Err(e) = self.handle_replies(reply_receiver) { error!(