aboutsummaryrefslogtreecommitdiff
path: root/src/net.cpp
diff options
context:
space:
mode:
authornicolas.dorier <nicolas.dorier@gmail.com>2019-06-20 18:37:51 +0900
committernicolas.dorier <nicolas.dorier@gmail.com>2019-08-11 11:33:27 +0900
commite5b26deaaa6842f7dd7c4537ede000f965ea0189 (patch)
treec45a24d8290b86ef74bb6b95287de5972768caa2 /src/net.cpp
parente5fdda68c6d2313edb74443f0d1e6d2ce2d97f5e (diff)
downloadbitcoin-e5b26deaaa6842f7dd7c4537ede000f965ea0189.tar.xz
Make whitebind/whitelist permissions more flexible
Diffstat (limited to 'src/net.cpp')
-rw-r--r--src/net.cpp59
1 files changed, 39 insertions, 20 deletions
diff --git a/src/net.cpp b/src/net.cpp
index 7d6eb31a7c..fb04650ed7 100644
--- a/src/net.cpp
+++ b/src/net.cpp
@@ -16,6 +16,7 @@
#include <crypto/common.h>
#include <crypto/sha256.h>
#include <netbase.h>
+#include <net_permissions.h>
#include <primitives/transaction.h>
#include <scheduler.h>
#include <ui_interface.h>
@@ -67,7 +68,6 @@ enum BindFlags {
BF_NONE = 0,
BF_EXPLICIT = (1U << 0),
BF_REPORT_ERROR = (1U << 1),
- BF_WHITELIST = (1U << 2),
};
// The set of sockets cannot be modified while waiting
@@ -459,12 +459,10 @@ void CNode::CloseSocketDisconnect()
}
}
-bool CConnman::IsWhitelistedRange(const CNetAddr &addr) {
- for (const CSubNet& subnet : vWhitelistedRange) {
- if (subnet.Match(addr))
- return true;
+void CConnman::AddWhitelistPermissionFlags(NetPermissionFlags& flags, const CNetAddr &addr) const {
+ for (const auto& subnet : vWhitelistedRange) {
+ if (subnet.m_subnet.Match(addr)) NetPermissions::AddFlag(flags, subnet.m_flags);
}
- return false;
}
std::string CNode::GetAddrName() const {
@@ -529,6 +527,7 @@ void CNode::copyStats(CNodeStats &stats)
X(nRecvBytes);
}
X(fWhitelisted);
+ X(m_permissionFlags);
{
LOCK(cs_feeFilter);
X(minFeeFilter);
@@ -904,7 +903,20 @@ void CConnman::AcceptConnection(const ListenSocket& hListenSocket) {
}
}
- bool whitelisted = hListenSocket.whitelisted || IsWhitelistedRange(addr);
+ NetPermissionFlags permissionFlags = NetPermissionFlags::PF_NONE;
+ hListenSocket.AddSocketPermissionFlags(permissionFlags);
+ AddWhitelistPermissionFlags(permissionFlags, addr);
+ const bool noban = NetPermissions::HasFlag(permissionFlags, NetPermissionFlags::PF_NOBAN);
+ bool legacyWhitelisted = false;
+ if (NetPermissions::HasFlag(permissionFlags, NetPermissionFlags::PF_ISIMPLICIT)) {
+ NetPermissions::ClearFlag(permissionFlags, PF_ISIMPLICIT);
+ if (gArgs.GetBoolArg("-whitelistforcerelay", false)) NetPermissions::AddFlag(permissionFlags, PF_FORCERELAY);
+ if (gArgs.GetBoolArg("-whitelistrelay", false)) NetPermissions::AddFlag(permissionFlags, PF_RELAY);
+ NetPermissions::AddFlag(permissionFlags, PF_MEMPOOL);
+ NetPermissions::AddFlag(permissionFlags, PF_NOBAN);
+ legacyWhitelisted = true;
+ }
+
{
LOCK(cs_vNodes);
for (const CNode* pnode : vNodes) {
@@ -941,7 +953,7 @@ void CConnman::AcceptConnection(const ListenSocket& hListenSocket) {
// Don't accept connections from banned peers, but if our inbound slots aren't almost full, accept
// if the only banning reason was an automatic misbehavior ban.
- if (!whitelisted && bannedlevel > ((nInbound + 1 < nMaxInbound) ? 1 : 0))
+ if (!noban && bannedlevel > ((nInbound + 1 < nMaxInbound) ? 1 : 0))
{
LogPrint(BCLog::NET, "connection from %s dropped (banned)\n", addr.ToString());
CloseSocket(hSocket);
@@ -962,9 +974,15 @@ void CConnman::AcceptConnection(const ListenSocket& hListenSocket) {
uint64_t nonce = GetDeterministicRandomizer(RANDOMIZER_ID_LOCALHOSTNONCE).Write(id).Finalize();
CAddress addr_bind = GetBindAddress(hSocket);
- CNode* pnode = new CNode(id, nLocalServices, GetBestHeight(), hSocket, addr, CalculateKeyedNetGroup(addr), nonce, addr_bind, "", true);
+ ServiceFlags nodeServices = nLocalServices;
+ if (NetPermissions::HasFlag(permissionFlags, PF_BLOOMFILTER)) {
+ nodeServices = static_cast<ServiceFlags>(nodeServices | NODE_BLOOM);
+ }
+ CNode* pnode = new CNode(id, nodeServices, GetBestHeight(), hSocket, addr, CalculateKeyedNetGroup(addr), nonce, addr_bind, "", true);
pnode->AddRef();
- pnode->fWhitelisted = whitelisted;
+ pnode->m_permissionFlags = permissionFlags;
+ // If this flag is present, the user probably expect that RPC and QT report it as whitelisted (backward compatibility)
+ pnode->fWhitelisted = legacyWhitelisted;
pnode->m_prefer_evict = bannedlevel > 0;
m_msgproc->InitializeNode(pnode);
@@ -1983,7 +2001,7 @@ void CConnman::ThreadMessageHandler()
-bool CConnman::BindListenPort(const CService &addrBind, std::string& strError, bool fWhitelisted)
+bool CConnman::BindListenPort(const CService& addrBind, std::string& strError, NetPermissionFlags permissions)
{
strError = "";
int nOne = 1;
@@ -2044,9 +2062,9 @@ bool CConnman::BindListenPort(const CService &addrBind, std::string& strError, b
return false;
}
- vhListenSocket.push_back(ListenSocket(hListenSocket, fWhitelisted));
+ vhListenSocket.push_back(ListenSocket(hListenSocket, permissions));
- if (addrBind.IsRoutable() && fDiscover && !fWhitelisted)
+ if (addrBind.IsRoutable() && fDiscover && (permissions & PF_NOBAN) == 0)
AddLocal(addrBind, LOCAL_BIND);
return true;
@@ -2130,11 +2148,11 @@ NodeId CConnman::GetNewNodeId()
}
-bool CConnman::Bind(const CService &addr, unsigned int flags) {
+bool CConnman::Bind(const CService &addr, unsigned int flags, NetPermissionFlags permissions) {
if (!(flags & BF_EXPLICIT) && !IsReachable(addr))
return false;
std::string strError;
- if (!BindListenPort(addr, strError, (flags & BF_WHITELIST) != 0)) {
+ if (!BindListenPort(addr, strError, permissions)) {
if ((flags & BF_REPORT_ERROR) && clientInterface) {
clientInterface->ThreadSafeMessageBox(strError, "", CClientUIInterface::MSG_ERROR);
}
@@ -2143,20 +2161,21 @@ bool CConnman::Bind(const CService &addr, unsigned int flags) {
return true;
}
-bool CConnman::InitBinds(const std::vector<CService>& binds, const std::vector<CService>& whiteBinds) {
+bool CConnman::InitBinds(const std::vector<CService>& binds, const std::vector<NetWhitebindPermissions>& whiteBinds)
+{
bool fBound = false;
for (const auto& addrBind : binds) {
- fBound |= Bind(addrBind, (BF_EXPLICIT | BF_REPORT_ERROR));
+ fBound |= Bind(addrBind, (BF_EXPLICIT | BF_REPORT_ERROR), NetPermissionFlags::PF_NONE);
}
for (const auto& addrBind : whiteBinds) {
- fBound |= Bind(addrBind, (BF_EXPLICIT | BF_REPORT_ERROR | BF_WHITELIST));
+ fBound |= Bind(addrBind.m_service, (BF_EXPLICIT | BF_REPORT_ERROR), addrBind.m_flags);
}
if (binds.empty() && whiteBinds.empty()) {
struct in_addr inaddr_any;
inaddr_any.s_addr = INADDR_ANY;
struct in6_addr inaddr6_any = IN6ADDR_ANY_INIT;
- fBound |= Bind(CService(inaddr6_any, GetListenPort()), BF_NONE);
- fBound |= Bind(CService(inaddr_any, GetListenPort()), !fBound ? BF_REPORT_ERROR : BF_NONE);
+ fBound |= Bind(CService(inaddr6_any, GetListenPort()), BF_NONE, NetPermissionFlags::PF_NONE);
+ fBound |= Bind(CService(inaddr_any, GetListenPort()), !fBound ? BF_REPORT_ERROR : BF_NONE, NetPermissionFlags::PF_NONE);
}
return fBound;
}