mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-09-13 06:04:42 +02:00
Merge bitcoin/bitcoin#35730: http: limit connected HTTPRemoteClients
bd4b1524eainit: do not count file descriptors for HTTPServer if -server=0 (Matthew Zipkin)b08662060dinit: account for maximum file descriptors needed by HTTP (Matthew Zipkin)cc2acebefbhttp: configure simultaneous connection limit with -rpcmaxconnections (Matthew Zipkin)b3d6d2d1a7http: limit connected clients to 16 (Matthew Zipkin)86651d8197scripted-diff: Rename nUserBind, nBind, nMaxConnections to snake_case (Matthew Zipkin) Pull request description: Introduces a new configuration option `-rpcmaxconnections` with default value `16`. This is used to limit the number of simultaneous `HTTPClient` connected to the `HTTPServer`. When the limit is reached, new pending connections remain queued in the kernel's socket buffer. Those connections have complete TCP handshakes with the kernel but do not occupy any application memory. The previous libevent-based HTTP server had no limit on connections but it did have a limit on the kernel socket queue:e7ff4ef2b4/http.c (L3510)```c if (listen(fd, 128) == -1) { ``` The current HTTP server, like the p2p server, uses a platform constant here:b6becf3534/src/httpserver.cpp (L743)(on my macOS `SOMAXCONN` is `128` but on my Debian machine it's `4096`) The default of 16 was chosen as a reasonable upper bound for single-user RPC use cases. Systems designed to handle more simultaneous HTTP connections than this (previously relying on the absence of a limit) can adjust the setting. ## File descriptors Because of the connection limit, we can now account for the maximum number of file descriptors needed by the HTTP server. This addresses several issues (#11368 #11322 maybe #27732) that could have been fixed by a PR waiting in vain for a libevent release (#27731). ## Bonus performance improvement The new limit is managed in a loop that drains the kernel's socket queue with `accept()`. All pending connections from the queue (up to the limit) are processed in one single call to `SocketHandlerListening()`. The previous code would only accept one connection from the queue on each I/O loop tick, with a `SELECT_TIMEOUT` (50ms) sleep between each. ACKs for top commit: fjahr: tACKbd4b1524eajanb84: ACKbd4b1524eawinterrdog: tested ACKbd4b1524eahodlinator: Concept ACKbd4b1524eawillcl-ark: ACKbd4b1524eaTree-SHA512: 2ef7a96da4d7037c7343ec0ea03fda5bb55d10c2a071fce4929141297515923b203d3d338dbcb6599849768f52aa3c9da509fb5d1d6f7c574a1d2034ea2a9e74
This commit is contained in:
@@ -41,6 +41,11 @@ inline constexpr int DEFAULT_HTTP_WORKQUEUE=64;
|
||||
|
||||
inline constexpr int DEFAULT_HTTP_SERVER_TIMEOUT=30;
|
||||
|
||||
/**
|
||||
* Maximum number of connected HTTP clients
|
||||
*/
|
||||
inline constexpr int DEFAULT_MAX_HTTP_CONNECTIONS = 16;
|
||||
|
||||
enum class HTTPRequestMethod {
|
||||
UNKNOWN,
|
||||
GET,
|
||||
@@ -311,6 +316,11 @@ public:
|
||||
*/
|
||||
void SetServerTimeout(std::chrono::seconds seconds) { m_rpcservertimeout = seconds; }
|
||||
|
||||
/**
|
||||
* Set the maximum amount of connected HTTPClients (-rpcmaxconnections)
|
||||
*/
|
||||
void SetMaxConnections(int max_conn) { m_rpcmaxconnections = max_conn; }
|
||||
|
||||
/**
|
||||
* Force-remove all remaining clients from m_connected without waiting for
|
||||
* graceful disconnection. Must only be called after JoinSocketsThreads().
|
||||
@@ -416,6 +426,11 @@ private:
|
||||
*/
|
||||
bool ClientAllowed(const CNetAddr& netaddr) const;
|
||||
|
||||
/**
|
||||
* Maximum amount of concurrent connections
|
||||
*/
|
||||
int m_rpcmaxconnections{DEFAULT_MAX_HTTP_CONNECTIONS};
|
||||
|
||||
/**
|
||||
* Accept a connection.
|
||||
* @param[in] listen_sock Socket on which to accept the connection.
|
||||
|
||||
Reference in New Issue
Block a user