ipc: support per-address max-connections options on -ipcbind #35036

pull enirox001 wants to merge 6 commits into bitcoin:master from enirox001:04-26-ipcbind-max-connections-draft changing 12 files +270 −24
  1. enirox001 commented at 1:07 pm on April 9, 2026: contributor

    This is a draft follow-up to #34978 to make the per-address IPC connection-limit approach concrete.

    The branch extends -ipcbind to accept :max-connections=<n> options, for example -ipcbind=unix::max-connections=8 or -ipcbind=unix:/custom/path:max-connections=8, instead of introducing a separate global -ipcmaxconnections option.

    It also vendors the local listener limit support needed in libmultiprocess and threads the parsed per-address limit through to ListenConnections() so each listener can stop accepting new IPC connections after reaching its local cap and resume accepting after a disconnect.

    The draft includes:

    • parser coverage for -ipcbind max-connections and invalid inputs
    • functional init coverage for FD reservation logging and init errors
    • an IPC behavior test verifying that with max_connections=1, a second client only becomes usable after the first disconnects

    This is intended to help evaluate the per-address approach downstream against the global-limit direction in #34978.

  2. test: assert file descriptors available is logged on -ipcbind startup
    Before adding IPC FD reservation, verify that the existing "file
    descriptors available" log line fires when the node starts with
    -ipcbind=unix. This establishes a baseline; the following commits
    rename this helper to test_ipcmaxconnections and extend it to assert
    the new reservation log line.
    f7e40ee984
  3. init: Reserve file descriptors for IPC connections
    When -ipcbind is used, the node opens one listening socket FD per
    bound address and accepts concurrent IPC connections. Neither was
    previously accounted for in min_required_fds, meaning IPC-heavy
    workloads could silently exhaust available file descriptors at
    unpredictable moments.
    
    Add -ipcmaxconnections (default: 16, mirroring -rpcworkqueue) so
    operators can control how many FDs are reserved for accepted IPC
    connections. Add ipc_bind to account for the listening socket FDs
    opened per -ipcbind address, which were previously unaccounted for.
    Emit a warning when -ipcmaxconnections is set without -ipcbind. Log
    the total IPC FD reservation at startup so operators can verify it.
    
    Suggested by Sjors in #32297 (comment).
    9139dfd704
  4. test: extend -ipcmaxconnections coverage to assert FD reservation logging
    Add -ipcmaxconnections startup checks and assert the new IPC FD
    reservation log line fires with correct values. With -ipcmaxconnections=8,
    the node logs "Reserving 9 file descriptors for IPC (1 listening sockets,
    8 accepted connections)", demonstrating that this PR increases the reserved
    FD count.
    365be355a5
  5. ipc: add per-address max-connections parsing for -ipcbind
    Replace the global -ipcmaxconnections option with per-address
    max-connections parsing on -ipcbind values. Update init argument
    documentation, parse and validate :max-connections=<n> suffixes, and
    reserve file descriptors by summing accepted-connection limits across
    all configured IPC listeners.
    
    Reject ambiguous syntax like unix:max-connections=8 so option-looking
    input is not silently treated as a literal socket path.
    
    Extend IPC parser coverage and functional startup coverage to check the
    new -ipcbind forms, FD reservation logging, and init errors for invalid
    max-connections values.
    467b0ee053
  6. ipc: pass per-address connection limits to ListenConnections
    Thread optional per-address max-connections values through the Bitcoin
    IPC stack and the vendored libmultiprocess listener implementation.
    
    Update interfaces::Ipc and ipc::Protocol listen methods to accept an
    optional connection limit, pass parsed -ipcbind limits from init, and
    use the vendored ListenConnections(..., max_connections) support so each
    listener stops accepting new IPC connections after reaching its local
    cap and resumes accepting after a disconnect.
    af82fba424
  7. ipc: test per-address connection limiting over unix sockets
    Add a Bitcoin-side IPC test covering the local listener limit behavior
    through ipc::Process and ipc::Protocol over a real unix socket.
    
    The new test starts a listener with max_connections=1, verifies the
    first client is served immediately, checks that a second client remains
    blocked while the first connection stays open, and then confirms the
    second client becomes usable after the first disconnects. This keeps the
    downstream draft from relying only on vendored libmultiprocess tests and
    startup log assertions.
    7cf7a43cd2
  8. DrahtBot commented at 1:08 pm on April 9, 2026: contributor

    The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.

    Reviews

    See the guideline for information on the review process. A summary of reviews will appear here.

    LLM Linter (✨ experimental)

    Possible typos and grammar issues:

    • “Valid address values are "unix" to listen on the default path, /node.sock, or "unix:/custom/path" to specify a custom path.” -> “Valid address values are "unix" to listen on the default path (/node.sock), or "unix:/custom/path" to specify a custom path.” [The current wording is grammatically broken and can make it unclear whether <datadir>/node.sock is itself an accepted value vs just describing the default path.]

    Possible places where named args for integral literals may be used (e.g. func(x, /*named_arg=*/0) in C++, and func(x, named_arg=0) in Python):

    • protocol->listen(serve_fd, “test-serve”, *init, /max_connections=/1) in src/ipc/test/ipc_test.cpp
    • check_bind(“unix::max-connections=8”, “unix:”, 8, “”) in src/ipc/test/ipc_tests.cpp
    • check_bind(“unix:path.sock:max-connections=8”, “unix:path.sock”, 8, “”) in src/ipc/test/ipc_tests.cpp

    2026-04-09 13:08:14

  9. enirox001 closed this on Apr 9, 2026

  10. ryanofsky commented at 2:19 pm on April 9, 2026: contributor

    Concept ACK. Reactions on the implementation:

    • BindAddress and IpcBindOption structs seem similar and could be deduplicated
    • ParseIpcBindOption function should probably be an interfaces::Ipc class method because init code is not supposed to depend directly on IPC functions (they are not compiled when ENABLE_IPC is off)
    • Would be nice if ParseIpcBindOption was more general and looked for generic :option1,option2=value style socat options at the end of the string after the unix: prefix. This would make it easier to support more options later, and I think make the function more readable than searching for hardcoded strings.
    • Would seem nice to pass BindAddress/IpcBindOption struct to listenAddress instead of separate arguments.
    • Nice that this is reserving file descriptors in addition to limiting connections so seems to be a complete solution.

    Do you want to maybe leave this open as a draft since it depends on https://github.com/bitcoin-core/libmultiprocess/pull/269?

    EDIT: Looks like this was replaced by #35037 (same code changes just rebased with squashed commits and small test change)

  11. enirox001 commented at 2:37 pm on April 9, 2026: contributor

    EDIT: Looks like this was replaced by #35037 (same code changes just rebased with squashed commits and small test change)

    Right, I replaced this with #35037 after rebasing onto master, cleaning the history down to 3 commits, and making a small functional test adjustments. Will apply the suggestions to that PR instead. Thanks


github-metadata-mirror

This is a metadata mirror of the GitHub repository bitcoin/bitcoin. This site is not affiliated with GitHub. Content is generated from a GitHub metadata backup.
generated: 2026-04-12 12:12 UTC

This site is hosted by @0xB10C
More mirrored repositories can be found on mirror.b10c.me