This PR changes the way how a ClientAllowed rejection is handled.
Currently whether to drop the connection to a refused client is the client's choice instead of the server.
A client whose address is not covered by -rpcallowip gets a 403 Forbidden, but the connection is not actively closed. This PR changes that by setting a Connection close header on reject and a change in the WriteReply() function makes that now the connection is closed based on a close requested by either side. The client is disconnected once the reply has been flushed.
So a rejected client asking for keep-alive (the HTTP/1.1 default) does not hold a slot until -rpcservertimeout
expires anymore. Whether to drop a refused connection should not be that peer's choice. This fixes a DDOS vector that will increase severity if #35730 is merged (due to the limited number of connections)
How to reproduce:
<details>
Start a bitcoin node with -rpcallowip=1.1.1.1 -rpcbind=<ip> -rpcservertimeout=30 -debug=http eg:
./build/bin/bitcoind --regtest -rpcallowip=1.1.1.1 -rpcbind=10.0.6.30 -rpcservertimeout=30 -debug=http
Run a timed netcat connection:
time { printf 'POST / HTTP/1.1\r\nHost: <ip>:18443\r\nConnection: keep-alive\r\nContent-Length: 0\r\n\r\n'; sleep 35; } | nc <ip> 18443
On master:
nc output:
HTTP/1.1 403 Forbidden
Date: Wed, 22 Jul 2026 11:45:51 GMT
Content-Length: 0
Content-Type: text/html; charset=ISO-8859-1
real 0m35.026s
user 0m0.009s
sys 0m0.012s
bitcoind log:
2026-07-22T11:45:51Z [http] HTTP Connection accepted from 10.0.6.30:56618 (id=1)
2026-07-22T11:45:51Z [http] Received a POST request for / from 10.0.6.30:56618 (id=1)
2026-07-22T11:45:51Z [http] HTTP request from 10.0.6.30:56618 rejected: Client network is not allowed RPC access
2026-07-22T11:45:51Z [http] HTTPResponse (status code: 403 size: 127) added to send buffer for client 10.0.6.30:56618 (id=1)
2026-07-22T11:45:51Z [http] Sent 127 bytes to client 10.0.6.30:56618 (id=1)
2026-07-22T11:46:21Z [http] HTTP client idle timeout 10.0.6.30:56618 (id=1)
2026-07-22T11:46:21Z [http] Disconnecting HTTP client 10.0.6.30:56618 (id=1)
This PR:
nc output:
HTTP/1.1 403 Forbidden
Date: Wed, 22 Jul 2026 11:48:09 GMT
Content-Length: 0
Content-Type: text/html; charset=ISO-8859-1
Connection: close
real 0m35.020s
user 0m0.012s
sys 0m0.011s
bitcoind log:
2026-07-22T11:48:09Z [http] HTTP Connection accepted from 10.0.6.30:56626 (id=0)
2026-07-22T11:48:09Z [http] Received a POST request for / from 10.0.6.30:56626 (id=0)
2026-07-22T11:48:09Z [http] HTTP request from 10.0.6.30:56626 rejected: Client network is not allowed RPC access
2026-07-22T11:48:09Z [http] HTTPResponse (status code: 403 size: 146) added to send buffer for client 10.0.6.30:56626 (id=0)
2026-07-22T11:48:09Z [http] Sent 146 bytes to client 10.0.6.30:56626 (id=0)
2026-07-22T11:48:09Z [http] Disconnecting HTTP client 10.0.6.30:56626 (id=0)
</details>