Bitcoin ABC 0.32.12
P2P Digital Currency
net_permissions.cpp
Go to the documentation of this file.
1// Copyright (c) 2009-2018 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 <net_permissions.h>
6
7#include <common/messages.h>
8#include <common/system.h>
9#include <netbase.h>
10#include <util/translation.h>
11
13
14const std::vector<std::string> NET_PERMISSIONS_DOC{
15 "bloomfilter (allow requesting BIP37 filtered blocks and transactions)",
16 "noban (do not ban for misbehavior; implies download)",
17 "forcerelay (relay transactions that are already in the mempool; implies "
18 "relay)",
19 "relay (relay even in -blocksonly mode, and unlimited transaction "
20 "announcements)",
21 "mempool (allow requesting BIP35 mempool contents)",
22 "download (allow getheaders during IBD, no disconnect after "
23 "maxuploadtarget limit)",
24 "bypass_proof_request_limits (experimental, bypass the limits on avalanche "
25 "proof downloads)",
26 "addr (responses to GETADDR avoid hitting the cache and contain random "
27 "records with the most up-to-date info)"};
28
29namespace {
30
31// Parse the following format: "perm1,perm2@xxxxxx"
32static bool
33TryParsePermissionFlags(const std::string &str, NetPermissionFlags &output,
34 ConnectionDirection *output_connection_direction,
35 size_t &readen, bilingual_str &error) {
38 const auto atSeparator = str.find('@');
39
40 // if '@' is not found (ie, "xxxxx"), the caller should apply implicit
41 // permissions
42 if (atSeparator == std::string::npos) {
44 readen = 0;
45 }
46 // else (ie, "perm1,perm2@xxxxx"), let's enumerate the permissions by
47 // splitting by ',' and calculate the flags
48 else {
49 readen = 0;
50 // permissions == perm1,perm2
51 const auto permissions = str.substr(0, atSeparator);
52 while (readen < permissions.length()) {
53 const auto commaSeparator = permissions.find(',', readen);
54 const auto len = commaSeparator == std::string::npos
55 ? permissions.length() - readen
56 : commaSeparator - readen;
57 // permission == perm1
58 const auto permission = permissions.substr(readen, len);
59 // We read "perm1"
60 readen += len;
61 if (commaSeparator != std::string::npos) {
62 // We read ","
63 readen++;
64 }
65
66 if (permission == "bloomfilter" || permission == "bloom") {
68 } else if (permission == "noban") {
70 } else if (permission == "forcerelay") {
72 } else if (permission == "mempool") {
74 } else if (permission == "download") {
76 } else if (permission == "all") {
78 } else if (permission == "relay") {
80 } else if (permission == "addr") {
82 } else if (permission == "in") {
83 connection_direction |= ConnectionDirection::In;
84 } else if (permission == "out") {
85 if (output_connection_direction == nullptr) {
86 // Only NetWhitebindPermissions() should pass a nullptr.
87 error = _("whitebind may only be used for incoming "
88 "connections (\"out\" was passed)");
89 return false;
90 }
91 connection_direction |= ConnectionDirection::Out;
92 } else if (permission == "bypass_proof_request_limits") {
95 } else if (permission.length() == 0) {
96 // Allow empty entries
97 } else {
98 error =
99 strprintf(_("Invalid P2P permission: '%s'"), permission);
100 return false;
101 }
102 }
103 readen++;
104 }
105
106 // By default, whitelist only applies to incoming connections
107 if (connection_direction == ConnectionDirection::None) {
108 connection_direction = ConnectionDirection::In;
109 } else if (flags == NetPermissionFlags::None) {
110 error =
111 strprintf(_("Only direction was set, no permissions: '%s'"), str);
112 return false;
113 }
114
115 output = flags;
116 if (output_connection_direction) {
117 *output_connection_direction = connection_direction;
118 }
119 error = Untranslated("");
120 return true;
121}
122
123} // namespace
124
126 std::vector<std::string> strings;
128 strings.push_back("bloomfilter");
129 }
131 strings.push_back("noban");
132 }
134 strings.push_back("forcerelay");
135 }
137 strings.push_back("relay");
138 }
140 strings.push_back("mempool");
141 }
143 strings.push_back("download");
144 }
146 strings.push_back("addr");
147 }
150 strings.push_back("bypass_proof_request_limits");
151 }
152 return strings;
153}
154
155bool NetWhitebindPermissions::TryParse(const std::string &str,
157 bilingual_str &error) {
159 size_t offset;
160 if (!TryParsePermissionFlags(str, flags,
161 /*output_connection_direction=*/nullptr,
162 offset, error)) {
163 return false;
164 }
165
166 const std::string strBind = str.substr(offset);
167 const std::optional<CService> addrBind{Lookup(strBind, 0, false)};
168 if (!addrBind.has_value()) {
169 error = ResolveErrMsg("whitebind", strBind);
170 return false;
171 }
172 if (addrBind.value().GetPort() == 0) {
173 error = strprintf(_("Need to specify a port with -whitebind: '%s'"),
174 strBind);
175 return false;
176 }
177
178 output.m_flags = flags;
179 output.m_service = addrBind.value();
180 error = Untranslated("");
181 return true;
182}
183
185 const std::string &str, NetWhitelistPermissions &output,
186 ConnectionDirection &output_connection_direction, bilingual_str &error) {
188 size_t offset;
189 // Only NetWhitebindPermissions should pass a nullptr for
190 // output_connection_direction.
191 if (!TryParsePermissionFlags(str, flags, &output_connection_direction,
192 offset, error)) {
193 return false;
194 }
195
196 const std::string net = str.substr(offset);
197 CSubNet subnet;
198 LookupSubNet(net, subnet);
199 if (!subnet.IsValid()) {
200 error =
201 strprintf(_("Invalid netmask specified in -whitelist: '%s'"), net);
202 return false;
203 }
204
205 output.m_flags = flags;
206 output.m_subnet = subnet;
207 error = Untranslated("");
208 return true;
209}
int flags
Definition: bitcoin-tx.cpp:546
bool IsValid() const
NetPermissionFlags m_flags
static void AddFlag(NetPermissionFlags &flags, NetPermissionFlags f)
static std::vector< std::string > ToStrings(NetPermissionFlags flags)
static bool HasFlag(NetPermissionFlags flags, NetPermissionFlags f)
static bool TryParse(const std::string &str, NetWhitebindPermissions &output, bilingual_str &error)
static bool TryParse(const std::string &str, NetWhitelistPermissions &output, ConnectionDirection &output_connection_direction, bilingual_str &error)
bilingual_str ResolveErrMsg(const std::string &optname, const std::string &strBind)
Definition: messages.cpp:58
const std::vector< std::string > NET_PERMISSIONS_DOC
NetPermissionFlags
bool LookupSubNet(const std::string &strSubnet, CSubNet &ret, DNSLookupFn dns_lookup_function)
Parse and resolve a specified subnet string into the appropriate internal representation.
Definition: netbase.cpp:881
std::vector< CService > Lookup(const std::string &name, uint16_t portDefault, bool fAllowLookup, unsigned int nMaxSolutions, DNSLookupFn dns_lookup_function)
Resolve a service string to its corresponding service.
Definition: netbase.cpp:224
ConnectionDirection
Definition: netbase.h:37
Bilingual messages:
Definition: translation.h:17
#define strprintf
Format arguments and return the string or write to given std::ostream (see tinyformat::format doc for...
Definition: tinyformat.h:1202
bilingual_str _(const char *psz)
Translation function.
Definition: translation.h:68
bilingual_str Untranslated(std::string original)
Mark a bilingual_str as untranslated.
Definition: translation.h:36