LCOV - code coverage report
Current view: top level - src - net_permissions.cpp (source / functions) Hit Total Coverage
Test: total_coverage.info Lines: 83 83 100.0 %
Date: 2020-09-26 01:30:44 Functions: 5 5 100.0 %

          Line data    Source code
       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        4480 : const std::vector<std::string> NET_PERMISSIONS_DOC{
      12         640 :     "bloomfilter (allow requesting BIP37 filtered blocks and transactions)",
      13         640 :     "noban (do not ban for misbehavior; implies download)",
      14         640 :     "forcerelay (relay transactions that are already in the mempool; implies relay)",
      15         640 :     "relay (relay even in -blocksonly mode)",
      16         640 :     "mempool (allow requesting BIP35 mempool contents)",
      17         640 :     "download (allow getheaders during IBD, no disconnect after maxuploadtarget limit)",
      18         640 :     "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          82 : bool TryParsePermissionFlags(const std::string str, NetPermissionFlags& output, size_t& readen, bilingual_str& error)
      25             : {
      26          82 :     NetPermissionFlags flags = PF_NONE;
      27          82 :     const auto atSeparator = str.find('@');
      28             : 
      29             :     // if '@' is not found (ie, "xxxxx"), the caller should apply implicit permissions
      30          82 :     if (atSeparator == std::string::npos) {
      31          11 :         NetPermissions::AddFlag(flags, PF_ISIMPLICIT);
      32          11 :         readen = 0;
      33          11 :     }
      34             :     // else (ie, "perm1,perm2@xxxxx"), let's enumerate the permissions by splitting by ',' and calculate the flags
      35             :     else {
      36          71 :         readen = 0;
      37             :         // permissions == perm1,perm2
      38          71 :         const auto permissions = str.substr(0, atSeparator);
      39         164 :         while (readen < permissions.length()) {
      40          95 :             const auto commaSeparator = permissions.find(',', readen);
      41          95 :             const auto len = commaSeparator == std::string::npos ? permissions.length() - readen : commaSeparator - readen;
      42             :             // permission == perm1
      43          95 :             const auto permission = permissions.substr(readen, len);
      44          95 :             readen += len; // We read "perm1"
      45          95 :             if (commaSeparator != std::string::npos) readen++; // We read ","
      46             : 
      47          95 :             if (permission == "bloomfilter" || permission == "bloom") NetPermissions::AddFlag(flags, PF_BLOOMFILTER);
      48          84 :             else if (permission == "noban") NetPermissions::AddFlag(flags, PF_NOBAN);
      49          26 :             else if (permission == "forcerelay") NetPermissions::AddFlag(flags, PF_FORCERELAY);
      50          17 :             else if (permission == "mempool") NetPermissions::AddFlag(flags, PF_MEMPOOL);
      51          14 :             else if (permission == "download") NetPermissions::AddFlag(flags, PF_DOWNLOAD);
      52          13 :             else if (permission == "all") NetPermissions::AddFlag(flags, PF_ALL);
      53          11 :             else if (permission == "relay") NetPermissions::AddFlag(flags, PF_RELAY);
      54           6 :             else if (permission == "addr") NetPermissions::AddFlag(flags, PF_ADDR);
      55           6 :             else if (permission.length() == 0); // Allow empty entries
      56             :             else {
      57           2 :                 error = strprintf(_("Invalid P2P permission: '%s'"), permission);
      58           2 :                 return false;
      59             :             }
      60          95 :         }
      61          69 :         readen++;
      62          71 :     }
      63             : 
      64          80 :     output = flags;
      65          80 :     error = Untranslated("");
      66          80 :     return true;
      67          82 : }
      68             : 
      69             : }
      70             : 
      71        8636 : std::vector<std::string> NetPermissions::ToStrings(NetPermissionFlags flags)
      72             : {
      73        8636 :     std::vector<std::string> strings;
      74        8636 :     if (NetPermissions::HasFlag(flags, PF_BLOOMFILTER)) strings.push_back("bloomfilter");
      75        8636 :     if (NetPermissions::HasFlag(flags, PF_NOBAN)) strings.push_back("noban");
      76        8636 :     if (NetPermissions::HasFlag(flags, PF_FORCERELAY)) strings.push_back("forcerelay");
      77        8636 :     if (NetPermissions::HasFlag(flags, PF_RELAY)) strings.push_back("relay");
      78        8636 :     if (NetPermissions::HasFlag(flags, PF_MEMPOOL)) strings.push_back("mempool");
      79        8636 :     if (NetPermissions::HasFlag(flags, PF_DOWNLOAD)) strings.push_back("download");
      80        8636 :     if (NetPermissions::HasFlag(flags, PF_ADDR)) strings.push_back("addr");
      81             :     return strings;
      82        8636 : }
      83             : 
      84          17 : bool NetWhitebindPermissions::TryParse(const std::string str, NetWhitebindPermissions& output, bilingual_str& error)
      85             : {
      86          17 :     NetPermissionFlags flags;
      87          17 :     size_t offset;
      88          17 :     if (!TryParsePermissionFlags(str, flags, offset, error)) return false;
      89             : 
      90          16 :     const std::string strBind = str.substr(offset);
      91          16 :     CService addrBind;
      92          16 :     if (!Lookup(strBind, addrBind, 0, false)) {
      93           3 :         error = ResolveErrMsg("whitebind", strBind);
      94           3 :         return false;
      95             :     }
      96          13 :     if (addrBind.GetPort() == 0) {
      97           1 :         error = strprintf(_("Need to specify a port with -whitebind: '%s'"), strBind);
      98           1 :         return false;
      99             :     }
     100             : 
     101          12 :     output.m_flags = flags;
     102          12 :     output.m_service = addrBind;
     103          12 :     error = Untranslated("");
     104          12 :     return true;
     105          17 : }
     106             : 
     107          65 : bool NetWhitelistPermissions::TryParse(const std::string str, NetWhitelistPermissions& output, bilingual_str& error)
     108             : {
     109          65 :     NetPermissionFlags flags;
     110          65 :     size_t offset;
     111          65 :     if (!TryParsePermissionFlags(str, flags, offset, error)) return false;
     112             : 
     113          64 :     const std::string net = str.substr(offset);
     114          64 :     CSubNet subnet;
     115          64 :     LookupSubNet(net, subnet);
     116          64 :     if (!subnet.IsValid()) {
     117           2 :         error = strprintf(_("Invalid netmask specified in -whitelist: '%s'"), net);
     118           2 :         return false;
     119             :     }
     120             : 
     121          62 :     output.m_flags = flags;
     122          62 :     output.m_subnet = subnet;
     123          62 :     error = Untranslated("");
     124          62 :     return true;
     125          65 : }

Generated by: LCOV version 1.15