Bitcoin Core  0.20.99
P2P Digital Currency
net_permissions.cpp
Go to the documentation of this file.
1 // Copyright (c) 2009-2019 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)",
14  "forcerelay (relay transactions that are already in the mempool; implies relay)",
15  "relay (relay even in -blocksonly mode)",
16  "mempool (allow requesting BIP35 mempool contents)",
17 };
18 
19 namespace {
20 
21 // The parse the following format "perm1,perm2@xxxxxx"
22 bool TryParsePermissionFlags(const std::string str, NetPermissionFlags& output, size_t& readen, bilingual_str& error)
23 {
25  const auto atSeparator = str.find('@');
26 
27  // if '@' is not found (ie, "xxxxx"), the caller should apply implicit permissions
28  if (atSeparator == std::string::npos) {
30  readen = 0;
31  }
32  // else (ie, "perm1,perm2@xxxxx"), let's enumerate the permissions by splitting by ',' and calculate the flags
33  else {
34  readen = 0;
35  // permissions == perm1,perm2
36  const auto permissions = str.substr(0, atSeparator);
37  while (readen < permissions.length()) {
38  const auto commaSeparator = permissions.find(',', readen);
39  const auto len = commaSeparator == std::string::npos ? permissions.length() - readen : commaSeparator - readen;
40  // permission == perm1
41  const auto permission = permissions.substr(readen, len);
42  readen += len; // We read "perm1"
43  if (commaSeparator != std::string::npos) readen++; // We read ","
44 
45  if (permission == "bloomfilter" || permission == "bloom") NetPermissions::AddFlag(flags, PF_BLOOMFILTER);
46  else if (permission == "noban") NetPermissions::AddFlag(flags, PF_NOBAN);
47  else if (permission == "forcerelay") NetPermissions::AddFlag(flags, PF_FORCERELAY);
48  else if (permission == "mempool") NetPermissions::AddFlag(flags, PF_MEMPOOL);
49  else if (permission == "all") NetPermissions::AddFlag(flags, PF_ALL);
50  else if (permission == "relay") NetPermissions::AddFlag(flags, PF_RELAY);
51  else if (permission.length() == 0); // Allow empty entries
52  else {
53  error = strprintf(_("Invalid P2P permission: '%s'"), permission);
54  return false;
55  }
56  }
57  readen++;
58  }
59 
60  output = flags;
61  error = Untranslated("");
62  return true;
63 }
64 
65 }
66 
68 {
69  std::vector<std::string> strings;
70  if (NetPermissions::HasFlag(flags, PF_BLOOMFILTER)) strings.push_back("bloomfilter");
71  if (NetPermissions::HasFlag(flags, PF_NOBAN)) strings.push_back("noban");
72  if (NetPermissions::HasFlag(flags, PF_FORCERELAY)) strings.push_back("forcerelay");
73  if (NetPermissions::HasFlag(flags, PF_RELAY)) strings.push_back("relay");
74  if (NetPermissions::HasFlag(flags, PF_MEMPOOL)) strings.push_back("mempool");
75  return strings;
76 }
77 
79 {
81  size_t offset;
82  if (!TryParsePermissionFlags(str, flags, offset, error)) return false;
83 
84  const std::string strBind = str.substr(offset);
85  CService addrBind;
86  if (!Lookup(strBind, addrBind, 0, false)) {
87  error = ResolveErrMsg("whitebind", strBind);
88  return false;
89  }
90  if (addrBind.GetPort() == 0) {
91  error = strprintf(_("Need to specify a port with -whitebind: '%s'"), strBind);
92  return false;
93  }
94 
95  output.m_flags = flags;
96  output.m_service = addrBind;
97  error = Untranslated("");
98  return true;
99 }
100 
102 {
104  size_t offset;
105  if (!TryParsePermissionFlags(str, flags, offset, error)) return false;
106 
107  const std::string net = str.substr(offset);
108  CSubNet subnet;
109  LookupSubNet(net, subnet);
110  if (!subnet.IsValid()) {
111  error = strprintf(_("Invalid netmask specified in -whitelist: '%s'"), net);
112  return false;
113  }
114 
115  output.m_flags = flags;
116  output.m_subnet = subnet;
117  error = Untranslated("");
118  return true;
119 }
unsigned short GetPort() const
Definition: netaddress.cpp:666
bilingual_str ResolveErrMsg(const std::string &optname, const std::string &strBind)
Definition: error.cpp:39
const std::vector< std::string > NET_PERMISSIONS_DOC
static void AddFlag(NetPermissionFlags &flags, NetPermissionFlags f)
Bilingual messages:
Definition: translation.h:16
#define strprintf
Format arguments and return the string or write to given std::ostream (see tinyformat::format doc for...
Definition: tinyformat.h:1164
bilingual_str Untranslated(std::string original)
Mark a bilingual_str as untranslated.
Definition: translation.h:40
bool LookupSubNet(const std::string &strSubnet, CSubNet &ret)
Parse and resolve a specified subnet string into the appropriate internal representation.
Definition: netbase.cpp:823
bool Lookup(const std::string &name, std::vector< CService > &vAddr, int portDefault, bool fAllowLookup, unsigned int nMaxSolutions)
Resolve a service string to its corresponding service.
Definition: netbase.cpp:205
bilingual_str _(const char *psz)
Translation function.
Definition: translation.h:57
A combination of a network address (CNetAddr) and a (TCP) port.
Definition: netaddress.h:139
static bool HasFlag(const NetPermissionFlags &flags, NetPermissionFlags f)
NetPermissionFlags
NetPermissionFlags m_flags
int flags
Definition: bitcoin-tx.cpp:509
bool IsValid() const
Definition: netaddress.cpp:883
static bool TryParse(const std::string str, NetWhitebindPermissions &output, bilingual_str &error)
bool error(const char *fmt, const Args &... args)
Definition: system.h:49
static bool TryParse(const std::string str, NetWhitelistPermissions &output, bilingual_str &error)
static std::vector< std::string > ToStrings(NetPermissionFlags flags)