http: support unix sockets #36434

pull pinheadmz wants to merge 10 commits into bitcoin:master from pinheadmz:http-unix-sockets changing 20 files +1301 −234
  1. pinheadmz commented at 6:10 PM on October 4, 2026: member

    Closes #5029

    Accept unix:<path> in options -rpcbind= (server) and -rpcconnect= (bitcoin-cli). Creates a unix socket at the path provided (not relative to datadir so aboslute path recommended). Because access is handled by the filesystem, -rpcallowip is ignored for unix sockets and not required at all if we are only binding to unix sockets.

    Authentication by username/password/cookie is still required.

    A new option --httpunix is added to the test framework and added to test_runner for rpc_bind.py and interface_http.py for CI, but (like --usecli) most other tests should also pass with that option. When set, bitcoind is started with -rpcbind=unix...which overrides tcp://localhost entirely. AuthProxy has been extended to connect directly to the unix socket.

    Try it out!

    bitcoind -regtest -rpcbind=unix:/tmp/bitcoin.sock
    bitcoin-cli -regtest -rpcconnect=unix:/tmp/bitcoin.sock getbestblockhash
    

    Refactored code:

    Back in #27375 we added unix socket support but it was isloated to the Proxy class. That created a bit of tech debt which we pay off in this PR. Two new classes are implemented:

    • UnixSocketAddr reflects the CService API for generic unix sockets, without bitcoin-p2p-specific attributes
    • SocketAddr holds a variant of UnixSocketAddr and Cservice so classes like Proxy and HTTPServer can operate on an abstract level, with either socket type.
    • CNetAddr and CService are left untouched -- they are somewhat dirty combinations of generic socket classes and bitcoin p2p code, adding unix sockets to those classes wouldn't make sense for bitcoin p2p operations and that's why this design was chosen.

    Follow-up suggestions:

    • On macos the default unix socket buffer size is only ~8k. In the functional tests we have to bump the python client socket buffer up to ~256k or the "throttle" tests will stall on macos. We could apply this socket option on the server side as well, only on macos... requires some bike shedding.
    • This option replaces TCP but it does not replace HTTP, there may be a more efficient transport protocol.

    Production code and test framework changes designed and authored by my own cranial meatball. Unit tests added by Opus. C++ cleaned up by Fable, security tightened by Kimi-k3 🧠 🤖 🤖 🤖

  2. netbase: introduce UnixSocketAddr class
    Include unit tests to ensure the API matches CService
    ca0fad7f2a
  3. netbase: introduce SocketAddr class 239ae12c68
  4. test: cover existing Proxy API 48e93b4ede
  5. netbase: refactor Proxy to use SocketAddr e4db363abe
  6. http: use SocketAddr instead of CService 60272af5a1
  7. http: support listening on UNIX domain sockets d75fd2be9e
  8. http: allow empty -rpcallowip if all bind addresses are unix sockets 82953cde03
  9. Enable unix sockets in test_framework: cover interface_http & rpc_bind
    Most functional tests will pass with --httpunix, which uses unix
    sockets instead of TCP for all RPC commands in the test. For now,
    only require interface_http, rpc_bind --httpunix in CI to cover
    the specific changes from this branch.
    8e7055b99c
  10. bitcoin-cli: support connecting on UNIX domain sockets 1d1215bd7b
  11. doc: add unix socket options to help and docs 6876eb2b51
  12. DrahtBot added the label RPC/REST/ZMQ on Oct 4, 2026
  13. DrahtBot commented at 6:10 PM on October 4, 2026: contributor

    <!--e57a25ab6845829454e8d69fc972939a-->

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

    <!--006a51241073e994b41acfe9ec718e94-->

    External sites

    <!--021abf342d371248e50ceaed478a90ca-->

    Reviews

    See the guideline and AI policy for information on the review process.

    Type Reviewers
    Concept ACK winterrdog, b-l-u-e

    If your review is incorrectly listed, please copy-paste <code>&lt;!--meta-tag:bot-skip--&gt;</code> into the comment that the bot should ignore.

    <!--174a7506f384e20aa4161008e828411d-->

    Conflicts

    Reviewers, this pull request conflicts with the following ones:

    • #36340 <sub><img src="https://drahtbot.space/ack_count/bitcoin/bitcoin/36340.svg"></sub> (util: cap Sock::WaitMany timeout to fix -rpcclienttimeout=0 on macOS by kriss39)
    • #36303 <sub><img src="https://drahtbot.space/ack_count/bitcoin/bitcoin/36303.svg"></sub> (http: Log bytes received from client, use to replace receive-throttle regression test by pinheadmz)
    • #36204 <sub><img src="https://drahtbot.space/ack_count/bitcoin/bitcoin/36204.svg"></sub> (http: disconnect clients that never finish a request by janb84)
    • #36187 <sub><img src="https://drahtbot.space/ack_count/bitcoin/bitcoin/36187.svg"></sub> (http: Restore requirement of IPv4 bind success by hodlinator)
    • #36159 <sub><img src="https://drahtbot.space/ack_count/bitcoin/bitcoin/36159.svg"></sub> (http: Improve HTTPRemoteClient::MaybeDisconnect() by hodlinator)
    • #35713 <sub><img src="https://drahtbot.space/ack_count/bitcoin/bitcoin/35713.svg"></sub> (Remove boost as a unit test runner by rustaceanrob)
    • #34729 <sub><img src="https://drahtbot.space/ack_count/bitcoin/bitcoin/34729.svg"></sub> (Reduce log noise by ajtowns)
    • #33954 <sub><img src="https://drahtbot.space/ack_count/bitcoin/bitcoin/33954.svg"></sub> (test: add functional test for outbound connection management by mzumsande)
    • #31260 <sub><img src="https://drahtbot.space/ack_count/bitcoin/bitcoin/31260.svg"></sub> (scripted-diff: Type-safe settings retrieval by ryanofsky)
    • #19461 <sub><img src="https://drahtbot.space/ack_count/bitcoin/bitcoin/19461.svg"></sub> (multiprocess: Add bitcoin-gui -ipcconnect option by ryanofsky)
    • #19460 <sub><img src="https://drahtbot.space/ack_count/bitcoin/bitcoin/19460.svg"></sub> (multiprocess: Add bitcoin-wallet -ipcconnect option by ryanofsky)
    • #17783 <sub><img src="https://drahtbot.space/ack_count/bitcoin/bitcoin/17783.svg"></sub> (common: Disallow calling IsArgSet() on ALLOW_LIST options by ryanofsky)
    • #17581 <sub><img src="https://drahtbot.space/ack_count/bitcoin/bitcoin/17581.svg"></sub> (refactor: Remove settings merge reverse precedence code by ryanofsky)
    • #17580 <sub><img src="https://drahtbot.space/ack_count/bitcoin/bitcoin/17580.svg"></sub> (refactor: Add ALLOW_LIST flags and enforce usage in CheckArgFlags by ryanofsky)
    • #17493 <sub><img src="https://drahtbot.space/ack_count/bitcoin/bitcoin/17493.svg"></sub> (util: Forbid ambiguous multiple assignments in config file by ryanofsky)
    • #10102 <sub><img src="https://drahtbot.space/ack_count/bitcoin/bitcoin/10102.svg"></sub> (Multiprocess bitcoin by ryanofsky)

    If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first.

    <!--5faf32d7da4f0f540f40219e4f7537a3-->

    LLM Linter (✨ experimental)

    Possible places where comparison-specific test macros should replace generic comparisons:

    • [test/functional/rpc_bind.py] assert sum([self.options.run_ipv4, self.options.run_ipv6, self.options.run_nonloopback, self.options.httpunix]) > 1 -> consider assert_greater_than(sum([...]), 1)

    <sup>2026-10-04 18:11:19</sup>

  14. winterrdog commented at 8:57 PM on October 4, 2026: contributor

    concept ACK


    users of other projects that rely on Core have always wanted sth similar to this and implemented workarounds in the meantime:

    there was also an attempt to add this back in 2017:

    unfortunately, that attempt ran into a limitation in libevent's HTTP client. supporting Unix Domain sockets in bitcoin-cli required a libevent patch to pass an already-open Unix socket connection to the HTTP client. this was eventually addressed in https://github.com/libevent/libevent/pull/1722, but by then Core had decided to moved away from libevent. anyway, with libevent dropped, this is no longer an issue

  15. pinheadmz commented at 9:09 PM on October 4, 2026: member

    Don't forget https://github.com/libevent/libevent/issues/1615 ! Its been a long time coming... now that that pesky little refactor is out of the way we can finally get to it ;-)

  16. b-l-u-e commented at 11:10 AM on October 5, 2026: contributor

    concept ACK...i found an issue by running two nodes and noticed that second node can take over a live rpc unix socket path, if two nodes use different datadirs but the same -rpcbind=unix:<path> the second node starts with no error..since it removes the first node socket file and creates its own then after that bitcoin cli talks to the second node.. the first node keeps running but becomes unreachable so with TCP the second bind fails with address already in use

    i reproduced this on regtest

    B=build/bin
    SOCK=/tmp/btc-hijack.sock
    mkdir -p /tmp/nodeA /tmp/nodeB
    ARGS="-regtest -daemon -listen=0 -rpcbind=unix:$SOCK -rpcuser=u -rpcpassword=p"
    CLI="$B/bitcoin-cli -regtest -rpcconnect=unix:$SOCK -rpcuser=u -rpcpassword=p -rpcwait"
    

    1: for node A

    $B/bitcoind -datadir=/tmp/nodeA $ARGS
    $CLI getrpcinfo | grep logpath && stat -c 'inode=%i' $SOCK
    
    output:
    Bitcoin Core starting
    "logpath": "/tmp/nodeA/regtest/debug.log"
    inode=2229678
    

    2: for node B

    $B/bitcoind -datadir=/tmp/nodeB $ARGS; sleep 2
    $CLI getrpcinfo | grep logpath && stat -c 'inode=%i' $SOCK
    
    output:
    Bitcoin Core starting                                  (as you can see node B starts without error)
    "logpath": "/tmp/nodeB/regtest/debug.log"              (cli now reaches B)
    inode=2229647   (and this replaces node A socket file)
    

    3: ss -xlp | grep btc-hijack

    output:
    u_str LISTEN ... /tmp/btc-hijack.sock ... pid=1684462  (this is for B)
    u_str LISTEN ... /tmp/btc-hijack.sock ... pid=1684363  (here A still listening but unreachable)
    

    4: $CLI stop; sleep 2

    output:
    Bitcoin Core stopping                                  (`stop` reached B)
    

    5: pgrep -a bitcoind

    output:
    1684363 build/bin/bitcoind -datadir=/tmp/nodeA ...     (A still running)
    

    6: $CLI -rpcwait=0 getblockcount

    output:
    error: Error while attempting to communicate with server unix:/tmp/btc-hijack.sock (Could not connect to the server)
    
    Make sure the bitcoind server is running and that you are connecting to the correct unix socket path.
    Use "bitcoin-cli -help" for more info.
    

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-10-05 19:51 UTC

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