Bitcoin Core 32.99.0
P2P Digital Currency
listen.cpp
Go to the documentation of this file.
1// Copyright (c) 2026-present The Bitcoin Core developers
2// Distributed under the MIT software license, see the accompanying
3// file COPYING or http://www.opensource.org/licenses/mit-license.php.
4
5#include <common/url.h>
6#include <interfaces/ipc.h>
7#include <util/strencodings.h>
8#include <util/string.h>
9#include <util/translation.h>
10
11#include <cstdint>
12#include <string>
13#include <string_view>
14#include <utility>
15
16namespace {
17util::Result<int64_t> ParseIntOption(std::string_view name, std::string_view value, int64_t min_val, int64_t max_val)
18{
19 if (value.empty()) return util::Error{Untranslated(strprintf("Missing value for %s option", name))};
20 const auto parsed{ToIntegral<int64_t>(value)};
21 if (!parsed) return util::Error{Untranslated(strprintf("Invalid %s value '%s'", name, value))};
22 if (*parsed < min_val) return util::Error{Untranslated(strprintf("%s must be at least %d", name, min_val))};
23 if (*parsed > max_val) return util::Error{Untranslated(strprintf("%s must be at most %d", name, max_val))};
24 return *parsed;
25}
26} // namespace
27
28namespace interfaces {
30{
31 constexpr std::string_view UNIX_PREFIX{"unix:"};
32
33 // Only Unix socket -ipcbind values support inline socket options. Leave
34 // other address families untouched so ipc::Process can report address
35 // scheme errors consistently with -ipcconnect.
36 if (!address.starts_with(UNIX_PREFIX)) {
37 return ipc::ListenAddress{.address = std::move(address)};
38 }
39
40 // Socket options follow the first comma:
41 // unix:,max-connections=8
42 // unix:/custom/path,max-connections=8
43 // Commas in socket paths must be URL-encoded as %2C.
44 //
45 // Subsequent commas separate individual options.
46 const size_t option_pos{address.find(',')};
47 if (option_pos == std::string::npos) {
48 return ipc::ListenAddress{.address = UrlDecode(address)};
49 }
50
51 const std::string_view address_view{address};
52
53 ipc::ListenAddress listen_address{
54 .address = UrlDecode(address_view.substr(0, option_pos)),
55 };
56
57 for (const std::string& option_str : util::SplitString(address_view.substr(option_pos + 1), ',')) {
58 if (option_str.empty()) {
59 return util::Error{Untranslated("Empty socket option")};
60 }
61 const size_t eq{option_str.find('=')};
62 const std::string_view name{std::string_view{option_str}.substr(0, eq)};
63 const std::string_view value{eq == std::string::npos ? std::string_view{} : std::string_view{option_str}.substr(eq + 1)};
64 if (name == "max-connections") {
65 auto parsed{ParseIntOption(name, value, 1, static_cast<int64_t>(ipc::MAX_CONNECTIONS))};
66 if (!parsed) return util::Error{util::ErrorString(parsed)};
67 listen_address.max_connections = static_cast<size_t>(*parsed);
68 } else {
69 return util::Error{Untranslated(strprintf("Unknown socket option '%s'", name))};
70 }
71 }
72
73 return listen_address;
74}
75} // namespace interfaces
static util::Result< ipc::ListenAddress > parseListenAddress(std::string address)
Parse an IPC listening address and its per-listener options.
Definition: listen.cpp:29
constexpr size_t MAX_CONNECTIONS
Maximum accepted client connection limit for an IPC listening socket.
Definition: types.h:27
std::vector< std::string > SplitString(std::string_view str, char sep)
Definition: string.h:153
bilingual_str ErrorString(const Result< T > &result)
Definition: result.h:93
const char * name
Definition: rest.cpp:71
std::string address
Socket address passed to ipc::Process::bind(), with any -ipcbind socket options stripped.
Definition: types.h:32
#define strprintf
Format arguments and return the string or write to given std::ostream (see tinyformat::format doc for...
Definition: tinyformat.h:1172
bilingual_str Untranslated(std::string original)
Mark a bilingual_str as untranslated.
Definition: translation.h:82
std::string UrlDecode(std::string_view url_encoded)
Definition: url.cpp:13