Bitcoin ABC 0.30.5
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/system.h>
8#include <netbase.h>
9#include <util/error.h>
10#include <util/translation.h>
11
12const std::vector<std::string> NET_PERMISSIONS_DOC{
13 "bloomfilter (allow requesting BIP37 filtered blocks and transactions)",
14 "noban (do not ban for misbehavior; implies download)",
15 "forcerelay (relay transactions that are already in the mempool; implies "
16 "relay)",
17 "relay (relay even in -blocksonly mode, and unlimited transaction "
18 "announcements)",
19 "mempool (allow requesting BIP35 mempool contents)",
20 "download (allow getheaders during IBD, no disconnect after "
21 "maxuploadtarget limit)",
22 "bypass_proof_request_limits (experimental, bypass the limits on avalanche "
23 "proof downloads)",
24 "addr (responses to GETADDR avoid hitting the cache and contain random "
25 "records with the most up-to-date info)"};
26
27namespace {
28
29// Parse the following format: "perm1,perm2@xxxxxx"
30static bool
31TryParsePermissionFlags(const std::string &str, NetPermissionFlags &output,
32 ConnectionDirection *output_connection_direction,
33 size_t &readen, bilingual_str &error) {
36 const auto atSeparator = str.find('@');
37
38 // if '@' is not found (ie, "xxxxx"), the caller should apply implicit
39 // permissions
40 if (atSeparator == std::string::npos) {
42 readen = 0;
43 }
44 // else (ie, "perm1,perm2@xxxxx"), let's enumerate the permissions by
45 // splitting by ',' and calculate the flags
46 else {
47 readen = 0;
48 // permissions == perm1,perm2
49 const auto permissions = str.substr(0, atSeparator);
50 while (readen < permissions.length()) {
51 const auto commaSeparator = permissions.find(',', readen);
52 const auto len = commaSeparator == std::string::npos
53 ? permissions.length() - readen
54 : commaSeparator - readen;
55 // permission == perm1
56 const auto permission = permissions.substr(readen, len);
57 // We read "perm1"
58 readen += len;
59 if (commaSeparator != std::string::npos) {
60 // We read ","
61 readen++;
62 }
63
64 if (permission == "bloomfilter" || permission == "bloom") {
66 } else if (permission == "noban") {
68 } else if (permission == "forcerelay") {
70 } else if (permission == "mempool") {
72 } else if (permission == "download") {
74 } else if (permission == "all") {
76 } else if (permission == "relay") {
78 } else if (permission == "addr") {
80 } else if (permission == "in") {
81 connection_direction |= ConnectionDirection::In;
82 } else if (permission == "out") {
83 if (output_connection_direction == nullptr) {
84 // Only NetWhitebindPermissions() should pass a nullptr.
85 error = _("whitebind may only be used for incoming "
86 "connections (\"out\" was passed)");
87 return false;
88 }
89 connection_direction |= ConnectionDirection::Out;
90 } else if (permission == "bypass_proof_request_limits") {
93 } else if (permission.length() == 0) {
94 // Allow empty entries
95 } else {
96 error =
97 strprintf(_("Invalid P2P permission: '%s'"), permission);
98 return false;
99 }
100 }
101 readen++;
102 }
103
104 // By default, whitelist only applies to incoming connections
105 if (connection_direction == ConnectionDirection::None) {
106 connection_direction = ConnectionDirection::In;
107 } else if (flags == NetPermissionFlags::None) {
108 error =
109 strprintf(_("Only direction was set, no permissions: '%s'"), str);
110 return false;
111 }
112
113 output = flags;
114 if (output_connection_direction) {
115 *output_connection_direction = connection_direction;
116 }
117 error = Untranslated("");
118 return true;
119}
120
121} // namespace
122
124 std::vector<std::string> strings;
126 strings.push_back("bloomfilter");
127 }
129 strings.push_back("noban");
130 }
132 strings.push_back("forcerelay");
133 }
135 strings.push_back("relay");
136 }
138 strings.push_back("mempool");
139 }
141 strings.push_back("download");
142 }
144 strings.push_back("addr");
145 }
148 strings.push_back("bypass_proof_request_limits");
149 }
150 return strings;
151}
152
153bool NetWhitebindPermissions::TryParse(const std::string &str,
157 size_t offset;
158 if (!TryParsePermissionFlags(str, flags,
159 /*output_connection_direction=*/nullptr,
160 offset, error)) {
161 return false;
162 }
163
164 const std::string strBind = str.substr(offset);
165 CService addrBind;
166 if (!Lookup(strBind, addrBind, 0, false)) {
167 error = ResolveErrMsg("whitebind", strBind);
168 return false;
169 }
170 if (addrBind.GetPort() == 0) {
171 error = strprintf(_("Need to specify a port with -whitebind: '%s'"),
172 strBind);
173 return false;
174 }
175
176 output.m_flags = flags;
177 output.m_service = addrBind;
178 error = Untranslated("");
179 return true;
180}
181
183 const std::string &str, NetWhitelistPermissions &output,
184 ConnectionDirection &output_connection_direction, bilingual_str &error) {
186 size_t offset;
187 // Only NetWhitebindPermissions should pass a nullptr for
188 // output_connection_direction.
189 if (!TryParsePermissionFlags(str, flags, &output_connection_direction,
190 offset, error)) {
191 return false;
192 }
193
194 const std::string net = str.substr(offset);
195 CSubNet subnet;
196 LookupSubNet(net, subnet);
197 if (!subnet.IsValid()) {
198 error =
199 strprintf(_("Invalid netmask specified in -whitelist: '%s'"), net);
200 return false;
201 }
202
203 output.m_flags = flags;
204 output.m_subnet = subnet;
205 error = Untranslated("");
206 return true;
207}
int flags
Definition: bitcoin-tx.cpp:541
A combination of a network address (CNetAddr) and a (TCP) port.
Definition: netaddress.h:545
uint16_t GetPort() const
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: error.cpp:44
bool error(const char *fmt, const Args &...args)
Definition: logging.h:226
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:781
bool Lookup(const std::string &name, std::vector< CService > &vAddr, uint16_t portDefault, bool fAllowLookup, unsigned int nMaxSolutions, DNSLookupFn dns_lookup_function)
Resolve a service string to its corresponding service.
Definition: netbase.cpp:223
ConnectionDirection
Definition: netbase.h:32
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