Bitcoin Core  21.99.0
P2P Digital Currency
net_permissions.cpp
Go to the documentation of this file.
1 // Copyright (c) 2009-2020 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 #include <netbase.h>
7 #include <util/error.h>
8 #include <util/system.h>
9 #include <util/translation.h>
10 
11 const std::vector<std::string> NET_PERMISSIONS_DOC{
12  "bloomfilter (allow requesting BIP37 filtered blocks and transactions)",
13  "noban (do not ban for misbehavior; implies download)",
14  "forcerelay (relay transactions that are already in the mempool; implies relay)",
15  "relay (relay even in -blocksonly mode, and unlimited transaction announcements)",
16  "mempool (allow requesting BIP35 mempool contents)",
17  "download (allow getheaders during IBD, no disconnect after maxuploadtarget limit)",
18  "addr (responses to GETADDR avoid hitting the cache and contain random records with the most up-to-date info)"
19 };
20 
21 namespace {
22 
23 // The parse the following format "perm1,perm2@xxxxxx"
24 bool TryParsePermissionFlags(const std::string str, NetPermissionFlags& output, size_t& readen, bilingual_str& error)
25 {
27  const auto atSeparator = str.find('@');
28 
29  // if '@' is not found (ie, "xxxxx"), the caller should apply implicit permissions
30  if (atSeparator == std::string::npos) {
32  readen = 0;
33  }
34  // else (ie, "perm1,perm2@xxxxx"), let's enumerate the permissions by splitting by ',' and calculate the flags
35  else {
36  readen = 0;
37  // permissions == perm1,perm2
38  const auto permissions = str.substr(0, atSeparator);
39  while (readen < permissions.length()) {
40  const auto commaSeparator = permissions.find(',', readen);
41  const auto len = commaSeparator == std::string::npos ? permissions.length() - readen : commaSeparator - readen;
42  // permission == perm1
43  const auto permission = permissions.substr(readen, len);
44  readen += len; // We read "perm1"
45  if (commaSeparator != std::string::npos) readen++; // We read ","
46 
47  if (permission == "bloomfilter" || permission == "bloom") NetPermissions::AddFlag(flags, PF_BLOOMFILTER);
48  else if (permission == "noban") NetPermissions::AddFlag(flags, PF_NOBAN);
49  else if (permission == "forcerelay") NetPermissions::AddFlag(flags, PF_FORCERELAY);
50  else if (permission == "mempool") NetPermissions::AddFlag(flags, PF_MEMPOOL);
51  else if (permission == "download") NetPermissions::AddFlag(flags, PF_DOWNLOAD);
52  else if (permission == "all") NetPermissions::AddFlag(flags, PF_ALL);
53  else if (permission == "relay") NetPermissions::AddFlag(flags, PF_RELAY);
54  else if (permission == "addr") NetPermissions::AddFlag(flags, PF_ADDR);
55  else if (permission.length() == 0); // Allow empty entries
56  else {
57  error = strprintf(_("Invalid P2P permission: '%s'"), permission);
58  return false;
59  }
60  }
61  readen++;
62  }
63 
64  output = flags;
65  error = Untranslated("");
66  return true;
67 }
68 
69 }
70 
72 {
73  std::vector<std::string> strings;
74  if (NetPermissions::HasFlag(flags, PF_BLOOMFILTER)) strings.push_back("bloomfilter");
75  if (NetPermissions::HasFlag(flags, PF_NOBAN)) strings.push_back("noban");
76  if (NetPermissions::HasFlag(flags, PF_FORCERELAY)) strings.push_back("forcerelay");
77  if (NetPermissions::HasFlag(flags, PF_RELAY)) strings.push_back("relay");
78  if (NetPermissions::HasFlag(flags, PF_MEMPOOL)) strings.push_back("mempool");
79  if (NetPermissions::HasFlag(flags, PF_DOWNLOAD)) strings.push_back("download");
80  if (NetPermissions::HasFlag(flags, PF_ADDR)) strings.push_back("addr");
81  return strings;
82 }
83 
85 {
87  size_t offset;
88  if (!TryParsePermissionFlags(str, flags, offset, error)) return false;
89 
90  const std::string strBind = str.substr(offset);
91  CService addrBind;
92  if (!Lookup(strBind, addrBind, 0, false)) {
93  error = ResolveErrMsg("whitebind", strBind);
94  return false;
95  }
96  if (addrBind.GetPort() == 0) {
97  error = strprintf(_("Need to specify a port with -whitebind: '%s'"), strBind);
98  return false;
99  }
100 
101  output.m_flags = flags;
102  output.m_service = addrBind;
103  error = Untranslated("");
104  return true;
105 }
106 
108 {
110  size_t offset;
111  if (!TryParsePermissionFlags(str, flags, offset, error)) return false;
112 
113  const std::string net = str.substr(offset);
114  CSubNet subnet;
115  LookupSubNet(net, subnet);
116  if (!subnet.IsValid()) {
117  error = strprintf(_("Invalid netmask specified in -whitelist: '%s'"), net);
118  return false;
119  }
120 
121  output.m_flags = flags;
122  output.m_subnet = subnet;
123  error = Untranslated("");
124  return true;
125 }
CService
A combination of a network address (CNetAddr) and a (TCP) port.
Definition: netaddress.h:551
_
bilingual_str _(const char *psz)
Translation function.
Definition: translation.h:57
PF_DOWNLOAD
@ PF_DOWNLOAD
Definition: net_permissions.h:28
LookupSubNet
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:678
NetPermissions::ToStrings
static std::vector< std::string > ToStrings(NetPermissionFlags flags)
Definition: net_permissions.cpp:71
PF_FORCERELAY
@ PF_FORCERELAY
Definition: net_permissions.h:26
flags
int flags
Definition: bitcoin-tx.cpp:512
PF_ALL
@ PF_ALL
Definition: net_permissions.h:38
PF_NONE
@ PF_NONE
Definition: net_permissions.h:18
NET_PERMISSIONS_DOC
const std::vector< std::string > NET_PERMISSIONS_DOC
Definition: net_permissions.cpp:11
bilingual_str
Bilingual messages:
Definition: translation.h:16
PF_RELAY
@ PF_RELAY
Definition: net_permissions.h:23
ResolveErrMsg
bilingual_str ResolveErrMsg(const std::string &optname, const std::string &strBind)
Definition: error.cpp:43
NetWhitelistPermissions::m_subnet
CSubNet m_subnet
Definition: net_permissions.h:71
NetPermissions::HasFlag
static bool HasFlag(const NetPermissionFlags &flags, NetPermissionFlags f)
Definition: net_permissions.h:46
NetWhitelistPermissions
Definition: net_permissions.h:67
Untranslated
bilingual_str Untranslated(std::string original)
Mark a bilingual_str as untranslated.
Definition: translation.h:40
NetPermissionFlags
NetPermissionFlags
Definition: net_permissions.h:17
NetWhitebindPermissions::m_service
CService m_service
Definition: net_permissions.h:64
NetWhitebindPermissions::TryParse
static bool TryParse(const std::string str, NetWhitebindPermissions &output, bilingual_str &error)
Definition: net_permissions.cpp:84
error.h
CSubNet
Definition: netaddress.h:480
CService::GetPort
uint16_t GetPort() const
Definition: netaddress.cpp:946
system.h
strprintf
#define strprintf
Format arguments and return the string or write to given std::ostream (see tinyformat::format doc for...
Definition: tinyformat.h:1164
PF_BLOOMFILTER
@ PF_BLOOMFILTER
Definition: net_permissions.h:20
NetPermissions::AddFlag
static void AddFlag(NetPermissionFlags &flags, NetPermissionFlags f)
Definition: net_permissions.h:50
translation.h
NetPermissions::m_flags
NetPermissionFlags m_flags
Definition: net_permissions.h:44
PF_MEMPOOL
@ PF_MEMPOOL
Definition: net_permissions.h:32
PF_ADDR
@ PF_ADDR
Definition: net_permissions.h:34
CSubNet::IsValid
bool IsValid() const
Definition: netaddress.cpp:1199
netbase.h
error
bool error(const char *fmt, const Args &... args)
Definition: system.h:50
PF_NOBAN
@ PF_NOBAN
Definition: net_permissions.h:30
Lookup
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:197
PF_ISIMPLICIT
@ PF_ISIMPLICIT
Definition: net_permissions.h:37
NetWhitebindPermissions
Definition: net_permissions.h:60
NetWhitelistPermissions::TryParse
static bool TryParse(const std::string str, NetWhitelistPermissions &output, bilingual_str &error)
Definition: net_permissions.cpp:107
net_permissions.h