#36434 http: support unix sockets
| Reviewability | Reviews | Agreement | Size | ||||
|---|---|---|---|---|---|---|---|
| #36434 http: support unix sockets | Ready | 0 | Strong | 754 + 793 tests | |||
|
|
|
|
| |||
Reviewability: ReadyStalePaused Agreement: StrongPositivePositive w/ caveatsNeutralMildDisputedBlockedCrickets Reviews: current code-review ACKs, then (+stale ACKs) and -NACKs; greener = more ACKs. Size: lines added or modified outside tests, then in tests; greener = smaller. | |||||||
Goal
Adds UNIX domain socket support to Bitcoin Core's HTTP RPC server and bitcoin-cli via the -rpcbind and -rpcconnect configuration options using unix and unix:<path> syntax. It introduces UnixSocketAddr and a SocketAddr variant in netbase to decouple generic endpoint handling from P2P-specific networking classes like CService, and updates Proxy and HTTPServer accordingly. When binding exclusively to UNIX domain sockets, -rpcallowip is no longer required and default TCP loopback listeners are disabled.
Problem: Local JSON-RPC and REST communication previously required TCP loopback connections, forcing node operators to manage IP-based allowlists instead of operating system filesystem permissions and incurring TCP stack overhead. Additionally, earlier UNIX socket support added in PR #27375 was isolated to the Proxy class, leaving technical debt where socket abstractions were tangled with P2P networking classes.
Evidence of importance:
- Closes issue #5029, an open feature request for UNIX domain socket support in RPC since 2014.
- Description notes that earlier UNIX socket support in #27375 created technical debt in Proxy that this PR resolves with generic abstractions.
Scope: Refactors networking abstractions across netbase and httpserver by replacing CService with SocketAddr (a std::variant of CService and UnixSocketAddr) in HTTPRemoteClient and Proxy. Includes substantial new unit tests in src/test/netbase_tests.cpp (+498 lines) and functional test framework support via --httpunix.
Risk of a mistake: medium (rpc_api, tooling, tests, docs). A mistake in socket path resolution or socket binding permissions could prevent local RPC access or inadvertently expose the RPC interface to unauthorized local users.
Changed since the previous assessment: Added release notes and documentation for JSON-RPC, and extended functional test coverage for bitcoin-cli over UNIX domain sockets in interface_bitcoin_cli.py and test_runner.py.
Reviewability
Ready
Nothing known that would invalidate a review now.
Waiting on (from the thread read):
- author: winterrdog's question about abstract sockets and suggestion to update the PR description 2026-10-16
Agreement
Strong
substantive support, no open objection (winterrdog, winterrdog)
Thread notes: Added hodlinator as a participant and recorded their question about the benefit of HTTP over unix sockets vs IPC, which was answered by pinheadmz. A typo remark in rc:4412188649 was omitted as a nit.
Objections, suggestions, and questions:
| Reviewer | Type | Harm, request, or question | Status | Must be | Author replied | Quote |
|---|---|---|---|---|---|---|
| b-l-u-e (contributor) | objection, correctness | A second node started with the same -rpcbind=unix:<path> will overwrite the live socket file without error, making the first node unreachable while it remains running. | fixed · fix pushed · author pushed changes adopting ipcbind parameter format to make sockets datadir-scoped by default | changed | yes | 2026-10-05: '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 socke' Status from: 2026-10-08: pinheadmz: 'This should also adderss @b-l-u-e concern about multiple processes messing with each others sockets.' |
| b-l-u-e (contributor) | objection, interface | bitcoin-cli sends the resolved IP in the HTTP Host header instead of the hostname passed via -rpcconnect=, introducing a behavior change/regression from master. | fixed · fix pushed · author pushed fix for Host header in bitcoin-cli | changed | yes | 2026-10-05: 'the host header contains the resolved IP instead of the hostname given in `-rpcconnect=localhost`' Status from: 2026-10-08: pinheadmz: 'fix `"Host:` header in bitcoin-cli (@b-l-u-e)' |
| winterrdog (contributor) | objection, correctness | On platforms where char is signed, non-ASCII UTF-8 bytes wrap to negative values and match c < 0x20, causing valid UTF-8 paths like /tmp/josé.sock to be replaced with "unix" in logs. | fixed · fix pushed · author fixed using unsigned char and std::ranges in push e34ffb6de9 | changed | yes | 2026-10-11: 'char is signed on some platforms (e.g. x86), so bytes above 0x7f are interpreted as negative values (they wrap around) and also match c < 0x20. this means a utf-8 path like /tmp/josé.sock could end up' Status from: 2026-10-28: pinheadmz: 'good suggestion thanks, using `std::ranges` and `unsigned char` here' |
| winterrdog (contributor) | suggestion, approach | Place Unix socket handling code behind an #ifdef HAVE_SOCKADDR_UN guard to avoid compiling unused code on unsupported platforms. | fixed · fix pushed · author added compile guard in push e34ffb6de9 | answered | yes | 2026-10-14: 'why don't we just put this behind an #ifdef HAVE_SOCKADDR_UN guard so we skip this code entirely on platforms that do not support unix sockets ?' Status from: 2026-10-28: pinheadmz: 'yep fair enough, putting behind a compile guard' |
| winterrdog (contributor) | suggestion, interface | Log host instead of strRPCBind in the bind failure warning to avoid redundant port strings when a port is included in the address. | fixed · fix pushed · author resolved this along with the GetBindAddresses refactor | answered | yes | 2026-10-15: 'strRPCBind can show up in the logs if the optional port is included in the bind address (e.g. 127.0.0.1:8332), leading to logs like this one: Could not bind RPC on address 127.0.0.1:8332 port 8332: Ad' Status from: 2026-10-28: pinheadmz: 'fixed this along with the `GetBindAddresses()` refactor.' |
| winterrdog (contributor) | question, correctness | Whether duplicate -rpcbind unix socket endpoints unlinking the earlier socket and rebinding silently without warning is intended behavior or should fail like TCP. | answered · author replied that duplicate binds are considered an acceptable edge case | answered | yes | 2026-10-15: 'if two -rpcbind values resolve to the same path (e.g. -rpcbind=unix and -rpcbind=unix:http.sock, or the same value in bitcoin.conf and perhaps on the command line), PreparePath() (later called in HTTP' Status from: 2026-10-28: pinheadmz: 'Heh that's kind of a funny edge case. We don't complain if a user sets `-rpcport=50000` twice for example. I think it's ' |
| winterrdog (contributor) | question, scope | Whether abstract namespace unix sockets should be supported in the future for Linux-specific setups. | open | answered | no | 2026-10-16: 'i saw UnixSocketAddr::SetSockAddr() handles empty and abstract namespace addresses, but we do not support binding or connecting to abstract sockets. do you think it is worth supporting them in the fut' |
| winterrdog (contributor) | suggestion, maintenance | Update the PR description to match the code regarding Unix socket path resolution. | open | answered | no | 2026-10-16: 'the docs, release notes and -help text already match the code, so i think the PR description just needs updating to reflect this, so other reviewers do not get tripped up by the mismatch' |
| winterrdog (contributor) | suggestion, maintenance | Refactor GetBindAddresses() to reduce cognitive load and streamline the control flow. | fixed · fix pushed · author adopted the suggested refactor with tweaks in push e34ffb6de9 | answered | yes | 2026-10-16: 'while reviewing GetBindAddresses(), i ended up rewriting it to lower the cognitive load a bit and help me get my head around the flow. thought i could share it and see what you think' Status from: 2026-10-28: pinheadmz: 'I think it's a good idea to clean this up now, thanks. Taking the suggestion and tweaking a bit more on top (comments an' |
| hodlinator (member) | question, usefulness | What is the benefit of allowing HTTP over unix sockets compared to using IPC over unix sockets, given executeRpc() is already exposed through IPC? | answered · author explained that unix sockets do not require capnproto or multiprocess mode and have a lower barrier to entry | answered | yes | 2026-10-29: 'What is the benefit of allowing HTTP over unix sockets compared to using IPC over unix sockets?' Status from: 2026-10-29: pinheadmz: 'You get the security advantage and possibly an efficiency advantage with a very low bar for entry. IPC requires capnproto, unix sockets only require platform support.' |
Support:
- winterrdog (contributor) (Concept ACK, 2026-10-04) [read]: users of other projects relying on Core have wanted Unix domain socket support, and previous libevent blockers are gone
- b-l-u-e (contributor) (Concept ACK, 2026-10-05): (no reason given) [not substantive]
- winterrdog (contributor) (Approach ACK, 2026-10-16) [read]: convinced by the implementation and design choices, particularly using std::variant over polymorphism for SocketAddr; security is tight
Participants:
- winterrdog (contributor, objection, 12 statements 2026-10-04 to 2026-10-16): Approach ACK; raised signed char bug (fixed), suggestions on compile guard and refactoring, and questions
- b-l-u-e (contributor, objection, 2 statements 2026-10-05 to 2026-10-05): Concept ACK; reported socket takeover on collision and Host header regression (both fixed)
- hodlinator (member, question, 2 statements 2026-10-29 to 2026-10-29): asked about the benefits of HTTP over unix sockets compared to IPC
Files
857 lines under test/bench/ci.
- src/test/netbase_tests.cpp +498/-0
- src/netbase.cpp +203/-25
- src/netbase.h +190/-16
- src/bitcoin-cli.cpp +133/-55
- src/httpserver.cpp +108/-51
- test/functional/rpc_bind.py +124/-7
- src/init.cpp +67/-43
- test/functional/interface_http.py +64/-17
- test/functional/interface_bitcoin_cli.py +45/-27
- doc/release-notes-36434.md +31/-0
- test/functional/test_framework/test_node.py +22/-2
- src/httpserver.h +9/-10
- test/functional/test_framework/netutil.py +15/-0
- src/test/httpserver_tests.cpp +7/-7
- doc/JSON-RPC-interface.md +12/-0
- test/functional/test_framework/authproxy.py +7/-3
- test/functional/test_framework/test_framework.py +7/-0
- test/functional/test_runner.py +3/-0
- src/qt/clientmodel.cpp +1/-1
- src/test/fuzz/http_request.cpp +1/-1
Card
The short text the ranking pass compares across PRs.
Adds UNIX domain socket support to the HTTP RPC server and bitcoin-cli using -rpcbind=unix[:path] and -rpcconnect=unix[:path]. This enables local RPC communication without TCP loopback overhead, relying on filesystem permissions instead of -rpcallowip. The PR also refactors netbase by introducing UnixSocketAddr and SocketAddr, resolving technical debt left from PR #27375. This closes issue #5029, a feature request open since 2014.
Data
thread read through 2026-10-29 (34 statements), head ccbace1c33
labels: RPC/REST/ZMQ
Categories
RPC / REST / ZMQ
P2 · user request
Closes a decade-old feature request (#5029) to support UNIX domain sockets for the HTTP RPC server and bitcoin-cli. This provides substantial user value by allowing filesystem permissions instead of IP allowlists and eliminating TCP loopback overhead.
Membership: Carries the RPC/REST/ZMQ label and directly modifies src/httpserver.cpp, src/bitcoin-cli.cpp, and RPC configuration handling.
Factors: security/stability 1, bug 0, performance 1, user value 2, leverage 1