#36204 http: disconnect clients that never finish a request

full analysis

https://github.com/bitcoin/bitcoin/pull/36204 · janb84 · +250/-12 in 4 files, 2 commits · labels: RPC/REST/ZMQ

Goal

  • Prevent slow-trickling HTTP clients from tying up RPC connection slots indefinitely
  • Protects RPC and REST callers from denial-of-service slot exhaustion

This pull request introduces an HTTP request completion deadline to prevent clients from monopolizing connection slots indefinitely. Previously, -rpcservertimeout only checked for socket inactivity, allowing a client to keep a slot occupied by trickling request bytes slowly enough to avoid the idle timeout. The fix arms a non-resettable deadline upon receiving the first byte of a request, terminating connections that fail to finish sending their request within the timeout window.

Problem: Because -rpcservertimeout resets whenever bytes are read, an unauthenticated client trickling data can consume an RPC connection slot forever without ever finishing an HTTP request. With connection slots capped by -rpcmaxconnections (default 16), a handful of trickling sockets can exhaust all available slots and block all subsequent RPC calls.

Category: RPC / REST / ZMQ (#3 of 52)

P2 · DoS protection

  • P2 because it prevents denial-of-service exhaustion of limited RPC connection slots
  • Protects node RPC availability even though exposure is typically limited to localhost

Prevents HTTP connection slot exhaustion through slowloris-style trickled requests. While RPC typically listens on localhost by default, unauthenticated local or network clients can starve all connection slots without reaching authentication.

Membership: Modifies src/httpserver.cpp and src/httpserver.h to manage client timeouts and connection lifecycles.

Factors: security/stability 2, bug 1, performance 0, user value 1, leverage 0

Reviewability: Ready

  • Ready to review
  • Clean state with feedback from the initial review round addressed

The code is clean, CI passes, and the author addressed reviewer feedback in recent updates.

Author status: active

Resolved concerns:

  • Reviewer hodlinator suggested micro-optimizing condition evaluation ordering, which the author pushed back on due to branch likelihood and register caching.
  • Reviewer hodlinator suggested adopting mockable steady clock infrastructure from #36159; left as follow-up since #36159 has not merged.

Agreement: Positive

  • Positive sentiment with initial review feedback addressed
  • Concept approval and detailed technical review on timeouts and tests (hodlinator)

Positive, with Concept ACK and review suggestions addressed (hodlinator)

The change received a Concept ACK from hodlinator with several suggestions on tests and timeout handling, all of which were addressed or answered by the author.

  • 2026-09-11 hodlinator: "Concept ACK 537944cb7869039912139793b58bc6296b64eebe"
  • 2026-09-14 janb84: addressed review feedback and updated tests

Objections:

ReviewerKindHarmStatusBlockingAuthor repliedQuote
hodlinatorapproachSuboptimal condition check ordering could cause minor unnecessary evaluation overheadresolvednoyes2026-09-11: "nanonit: Feels like !m_req_busy would be the cheapest check and be the first one (same for is_idle)."
Settled: 2026-09-14: "Have to pushback on this one, m_req_busy is mostly false so the negate makes that true. It would cause an extra check that is mostly true and therefor does not short the evaluation."

Support:

  • hodlinator: Concept ACK 537944cb7869039912139793b58bc6296b64eebe [not substantive]

Participants: hodlinator (support)

State derived from the lists: support without stated reasons, no open objection (hodlinator)

Review verdicts (DrahtBot): 0

Files

193 lines under test/bench/ci.

  • src/test/httpserver_tests.cpp +120/-10
  • test/functional/interface_http.py +63/-0
  • src/httpserver.cpp +42/-2
  • src/httpserver.h +25/-0

Card

Adds a completion deadline for incoming HTTP requests so clients cannot monopolize connection slots by trickling data indefinitely. Currently, the idle timeout resets on every received byte, allowing an attacker or slow client to exhaust -rpcmaxconnections without ever sending a full request or reaching authentication. Reviewer hodlinator provided a Concept ACK and detailed review comments that the author addressed. The PR is ready for review with unit and functional test coverage.

Data

dossier JSON · extract JSON · model openrouter/google/gemini-3.8-flash, generated 2026-09-17T21:49, confidence high, input hash ecf59fed72aa1c6e