Skip to content

Commit

Permalink
net: move nLocalServices/nRelevantServices to CConnman
Browse files Browse the repository at this point in the history
These are in-turn passed to CNode at connection time. This allows us to offer
different services to different peers (or test the effects of doing so).
  • Loading branch information
theuni authored and Fuzzbawls committed Aug 25, 2020
1 parent bcee6ae commit 481929f
Show file tree
Hide file tree
Showing 8 changed files with 52 additions and 30 deletions.
5 changes: 4 additions & 1 deletion src/init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1094,6 +1094,9 @@ bool AppInit2()
fIsBareMultisigStd = GetBoolArg("-permitbaremultisig", DEFAULT_PERMIT_BAREMULTISIG);
nMaxDatacarrierBytes = GetArg("-datacarriersize", nMaxDatacarrierBytes);

ServiceFlags nLocalServices = NODE_NETWORK;
ServiceFlags nRelevantServices = NODE_NETWORK;

if (GetBoolArg("-peerbloomfilters", DEFAULT_PEERBLOOMFILTERS))
nLocalServices = ServiceFlags(nLocalServices | NODE_BLOOM);

Expand Down Expand Up @@ -1875,7 +1878,7 @@ bool AppInit2()
StartTorControl(threadGroup);

std::string strNodeError;
if(!StartNode(connman, threadGroup, scheduler, strNodeError))
if(!StartNode(connman, threadGroup, scheduler, nLocalServices, nRelevantServices, strNodeError))
return UIError(strNodeError);

#ifdef ENABLE_WALLET
Expand Down
4 changes: 2 additions & 2 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5352,7 +5352,7 @@ bool static ProcessMessage(CNode* pfrom, std::string strCommand, CDataStream& vR
if (!pfrom->fInbound) {
// Advertise our address
if (fListen && !IsInitialBlockDownload()) {
CAddress addr = GetLocalAddress(&pfrom->addr);
CAddress addr = GetLocalAddress(&pfrom->addr, pfrom->GetLocalServices());
FastRandomContext insecure_rand;
if (addr.IsRoutable()) {
LogPrintf("ProcessMessages: advertising address %s\n", addr.ToString());
Expand Down Expand Up @@ -5954,7 +5954,7 @@ bool static ProcessMessage(CNode* pfrom, std::string strCommand, CDataStream& vR
}
}

else if (!(nLocalServices & NODE_BLOOM) &&
else if (!(pfrom->GetLocalServices() & NODE_BLOOM) &&
(strCommand == NetMsgType::FILTERLOAD ||
strCommand == NetMsgType::FILTERADD ||
strCommand == NetMsgType::FILTERCLEAR)) {
Expand Down
32 changes: 18 additions & 14 deletions src/net.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,15 +69,11 @@ const int MAX_OUTBOUND_CONNECTIONS = 16;
const int MAX_FEELER_CONNECTIONS = 1;
}

/** Services this node implementation cares about */
static const ServiceFlags nRelevantServices = NODE_NETWORK;

//
// Global state variables
//
bool fDiscover = true;
bool fListen = true;
ServiceFlags nLocalServices = NODE_NETWORK;
RecursiveMutex cs_mapLocalHost;
std::map<CNetAddr, LocalServiceInfo> mapLocalHost;
static bool vfLimited[NET_MAX] = {};
Expand Down Expand Up @@ -154,7 +150,7 @@ static std::vector<CAddress> convertSeed6(const std::vector<SeedSpec6>& vSeedsIn
// Otherwise, return the unroutable 0.0.0.0 but filled in with
// the normal parameters, since the IP may be changed to a useful
// one by discovery.
CAddress GetLocalAddress(const CNetAddr* paddrPeer)
CAddress GetLocalAddress(const CNetAddr* paddrPeer, ServiceFlags nLocalServices)
{
CAddress ret(CService(CNetAddr(), GetListenPort()), NODE_NONE);
CService addr;
Expand Down Expand Up @@ -225,7 +221,7 @@ bool IsPeerAddrLocalGood(CNode* pnode)
void AdvertiseLocal(CNode* pnode)
{
if (fListen && pnode->fSuccessfullyConnected) {
CAddress addrLocal = GetLocalAddress(&pnode->addr);
CAddress addrLocal = GetLocalAddress(&pnode->addr, pnode->GetLocalServices());
// If discovery is enabled, sometimes give our peer the address it
// tells us that it sees us as in case it has a better idea of our
// address than we do.
Expand Down Expand Up @@ -425,7 +421,7 @@ CNode* CConnman::ConnectNode(CAddress addrConnect, const char* pszDest, bool fCo
addrman.Attempt(addrConnect, fCountFailure);

// Add node
CNode* pnode = new CNode(GetNewNodeId(), hSocket, addrConnect, pszDest ? pszDest : "", false);
CNode* pnode = new CNode(GetNewNodeId(), nLocalServices, hSocket, addrConnect, pszDest ? pszDest : "", false);
GetNodeSignals().InitializeNode(pnode->GetId(), pnode);
pnode->AddRef();

Expand Down Expand Up @@ -500,7 +496,7 @@ void CNode::PushVersion()
/// when NTP implemented, change to just nTime = GetAdjustedTime()
int64_t nTime = (fInbound ? GetAdjustedTime() : GetTime());
CAddress addrYou = (addr.IsRoutable() && !IsProxy(addr) ? addr : CAddress(CService(), addr.nServices));
CAddress addrMe = GetLocalAddress(&addr);
CAddress addrMe = GetLocalAddress(&addr, nLocalServices);
if (fLogIPs)
LogPrint(BCLog::NET, "send version message: version %d, blocks=%d, us=%s, them=%s, peer=%d\n", PROTOCOL_VERSION, nBestHeight, addrMe.ToString(), addrYou.ToString(), id);
else
Expand Down Expand Up @@ -1048,7 +1044,7 @@ void CConnman::AcceptConnection(const ListenSocket& hListenSocket) {
}
}

CNode* pnode = new CNode(GetNewNodeId(), hSocket, addr, "", true);
CNode* pnode = new CNode(GetNewNodeId(), nLocalServices, hSocket, addr, "", true);
GetNodeSignals().InitializeNode(pnode->GetId(), pnode);
pnode->AddRef();
pnode->fWhitelisted = whitelisted;
Expand Down Expand Up @@ -1968,11 +1964,11 @@ CConnman::CConnman()
nReceiveFloodSize = 0;
}

bool StartNode(CConnman& connman, boost::thread_group& threadGroup, CScheduler& scheduler, std::string& strNodeError)
bool StartNode(CConnman& connman, boost::thread_group& threadGroup, CScheduler& scheduler, ServiceFlags nLocalServices, ServiceFlags nRelevantServices, std::string& strNodeError)
{
Discover(threadGroup);

bool ret = connman.Start(threadGroup, scheduler, strNodeError);
bool ret = connman.Start(threadGroup, scheduler, nLocalServices, nRelevantServices, strNodeError);

return ret;
}
Expand All @@ -1982,10 +1978,12 @@ NodeId CConnman::GetNewNodeId()
return nLastNodeId.fetch_add(1, std::memory_order_relaxed);
}

bool CConnman::Start(boost::thread_group& threadGroup, CScheduler& scheduler, std::string& strNodeError)
bool CConnman::Start(boost::thread_group& threadGroup, CScheduler& scheduler, ServiceFlags nLocalServicesIn, ServiceFlags nRelevantServicesIn, std::string& strNodeError)
{
nTotalBytesRecv = 0;
nTotalBytesSent = 0;
nLocalServices = nLocalServicesIn;
nRelevantServices = nRelevantServicesIn;

nSendBufferMaxSize = 1000*GetArg("-maxsendbuffer", DEFAULT_MAXSENDBUFFER);
nReceiveFloodSize = 1000*GetArg("-maxreceivebuffer", DEFAULT_MAXRECEIVEBUFFER);
Expand Down Expand Up @@ -2037,7 +2035,7 @@ bool CConnman::Start(boost::thread_group& threadGroup, CScheduler& scheduler, st
if (pnodeLocalHost == nullptr) {
CNetAddr local;
LookupHost("127.0.0.1", local, false);
pnodeLocalHost = new CNode(GetNewNodeId(), INVALID_SOCKET, CAddress(CService(local, 0), nLocalServices));
pnodeLocalHost = new CNode(GetNewNodeId(), nLocalServices, INVALID_SOCKET, CAddress(CService(local, 0), nLocalServices));
GetNodeSignals().InitializeNode(pnodeLocalHost->GetId(), pnodeLocalHost);
}

Expand Down Expand Up @@ -2360,6 +2358,11 @@ uint64_t CConnman::GetTotalBytesSent()
return nTotalBytesSent;
}

ServiceFlags CConnman::GetLocalServices() const
{
return nLocalServices;
}

void CNode::Fuzz(int nChance)
{
if (!fSuccessfullyConnected) return; // Don't fuzz initial handshake
Expand Down Expand Up @@ -2397,7 +2400,7 @@ void CNode::Fuzz(int nChance)
unsigned int CConnman::GetReceiveFloodSize() const { return nReceiveFloodSize; }
unsigned int CConnman::GetSendBufferSize() const{ return nSendBufferMaxSize; }

CNode::CNode(NodeId idIn, SOCKET hSocketIn, const CAddress& addrIn, const std::string& addrNameIn, bool fInboundIn) :
CNode::CNode(NodeId idIn, ServiceFlags nLocalServicesIn, SOCKET hSocketIn, const CAddress& addrIn, const std::string& addrNameIn, bool fInboundIn) :
ssSend(SER_NETWORK, INIT_PROTO_VERSION),
addr(addrIn),
nKeyedNetGroup(CalculateKeyedNetGroup(addrIn)),
Expand Down Expand Up @@ -2444,6 +2447,7 @@ CNode::CNode(NodeId idIn, SOCKET hSocketIn, const CAddress& addrIn, const std::s
nMinPingUsecTime = std::numeric_limits<int64_t>::max();
id = idIn;
nOptimisticBytesWritten = 0;
nLocalServices = nLocalServicesIn;

GetRandBytes((unsigned char*)&nLocalHostNonce, sizeof(nLocalHostNonce));

Expand Down
24 changes: 19 additions & 5 deletions src/net.h
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ class CConnman

CConnman();
~CConnman();
bool Start(boost::thread_group& threadGroup, CScheduler& scheduler, std::string& strNodeError);
bool Start(boost::thread_group& threadGroup, CScheduler& scheduler, ServiceFlags nLocalServicesIn, ServiceFlags nRelevantServicesIn, std::string& strNodeError);
void Stop();
bool BindListenPort(const CService &bindAddr, std::string& strError, bool fWhitelisted = false);
bool OpenNetworkConnection(const CAddress& addrConnect, bool fCountFailure, CSemaphoreGrant* grantOutbound = NULL, const char* strDest = NULL, bool fOneShot = false, bool fFeeler = false);
Expand Down Expand Up @@ -181,6 +181,8 @@ class CConnman

void AddWhitelistedRange(const CSubNet& subnet);

ServiceFlags GetLocalServices() const;

uint64_t GetTotalBytesRecv();
uint64_t GetTotalBytesSent();

Expand Down Expand Up @@ -257,12 +259,18 @@ class CConnman
mutable RecursiveMutex cs_vNodes;
std::atomic<NodeId> nLastNodeId;
boost::condition_variable messageHandlerCondition;

/** Services this instance offers */
ServiceFlags nLocalServices;

/** Services this instance cares about */
ServiceFlags nRelevantServices;
};
extern std::unique_ptr<CConnman> g_connman;
void MapPort(bool fUseUPnP);
unsigned short GetListenPort();
bool BindListenPort(const CService& bindAddr, std::string& strError, bool fWhitelisted = false);
bool StartNode(CConnman& connman, boost::thread_group& threadGroup, CScheduler& scheduler, std::string& strNodeError);
bool StartNode(CConnman& connman, boost::thread_group& threadGroup, CScheduler& scheduler, ServiceFlags nLocalServices, ServiceFlags nRelevantServices, std::string& strNodeError);
bool StopNode(CConnman& connman);
size_t SocketSendData(CNode* pnode);
void CheckOffsetDisconnectedPeers(const CNetAddr& ip);
Expand Down Expand Up @@ -318,13 +326,13 @@ bool IsLocal(const CService& addr);
bool GetLocal(CService& addr, const CNetAddr* paddrPeer = NULL);
bool IsReachable(enum Network net);
bool IsReachable(const CNetAddr& addr);
CAddress GetLocalAddress(const CNetAddr* paddrPeer = NULL);
CAddress GetLocalAddress(const CNetAddr* paddrPeer, ServiceFlags nLocalServices);

bool validateMasternodeIP(const std::string& addrStr); // valid, reachable and routable address


extern bool fDiscover;
extern bool fListen;
extern ServiceFlags nLocalServices;

/** Maximum number of connections to simultaneously allow (aka connection slots) */
extern int nMaxConnections;
Expand Down Expand Up @@ -504,7 +512,7 @@ class CNode
// Whether a ping is requested.
bool fPingQueued;

CNode(NodeId id, SOCKET hSocketIn, const CAddress& addrIn, const std::string& addrNameIn = "", bool fInboundIn = false);
CNode(NodeId id, ServiceFlags nLocalServicesIn, SOCKET hSocketIn, const CAddress& addrIn, const std::string& addrNameIn = "", bool fInboundIn = false);
~CNode();

private:
Expand All @@ -514,6 +522,7 @@ class CNode
static uint64_t CalculateKeyedNetGroup(const CAddress& ad);

uint64_t nLocalHostNonce;
ServiceFlags nLocalServices;
public:
NodeId GetId() const
{
Expand Down Expand Up @@ -814,6 +823,11 @@ class CNode
bool DisconnectOldProtocol(int nVersionRequired, std::string strLastCommand = "");

void copyStats(CNodeStats& stats);

ServiceFlags GetLocalServices() const
{
return nLocalServices;
}
};

class CExplicitNetCleanup
Expand Down
2 changes: 1 addition & 1 deletion src/rpc/misc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ UniValue getinfo(const JSONRPCRequest& request)
std::string services;
for (int i = 0; i < 8; i++) {
uint64_t check = 1 << i;
if (nLocalServices & check) {
if (g_connman->GetLocalServices() & check) {
switch (check) {
case NODE_NETWORK:
services+= "NETWORK/";
Expand Down
3 changes: 2 additions & 1 deletion src/rpc/net.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -381,7 +381,8 @@ UniValue getnetworkinfo(const JSONRPCRequest& request)
obj.push_back(Pair("version", CLIENT_VERSION));
obj.push_back(Pair("subversion", strSubVersion));
obj.push_back(Pair("protocolversion", PROTOCOL_VERSION));
obj.push_back(Pair("localservices", strprintf("%016x", nLocalServices)));
if (g_connman)
obj.push_back(Pair("localservices", strprintf("%016x", g_connman->GetLocalServices())));
obj.push_back(Pair("timeoffset", GetTimeOffset()));
if(g_connman)
obj.push_back(Pair("connections", (int)g_connman->GetNodeCount(CConnman::CONNECTIONS_ALL)));
Expand Down
8 changes: 4 additions & 4 deletions src/test/DoS_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ BOOST_AUTO_TEST_CASE(DoS_banning)
{
connman->ClearBanned();
CAddress addr1(ip(0xa0b0c001), NODE_NONE);
CNode dummyNode1(id++, INVALID_SOCKET, addr1, "", true);
CNode dummyNode1(id++, NODE_NETWORK, INVALID_SOCKET, addr1, "", true);
GetNodeSignals().InitializeNode(dummyNode1.GetId(), &dummyNode1);
dummyNode1.nVersion = 1;
misbehave(dummyNode1.GetId(), 100); // Should get banned
Expand All @@ -65,7 +65,7 @@ BOOST_AUTO_TEST_CASE(DoS_banning)
BOOST_CHECK(!connman->IsBanned(ip(0xa0b0c001|0x0000ff00))); // Different IP, not banned

CAddress addr2(ip(0xa0b0c002), NODE_NONE);
CNode dummyNode2(id++, INVALID_SOCKET, addr2, "", true);
CNode dummyNode2(id++, NODE_NETWORK, INVALID_SOCKET, addr2, "", true);
GetNodeSignals().InitializeNode(dummyNode2.GetId(), &dummyNode2);
dummyNode2.nVersion = 1;
misbehave(dummyNode2.GetId(), 50);
Expand All @@ -82,7 +82,7 @@ BOOST_AUTO_TEST_CASE(DoS_banscore)
connman->ClearBanned();
mapArgs["-banscore"] = "111"; // because 11 is my favorite number
CAddress addr1(ip(0xa0b0c001), NODE_NONE);
CNode dummyNode1(id++, INVALID_SOCKET, addr1, "", true);
CNode dummyNode1(id++, NODE_NETWORK, INVALID_SOCKET, addr1, "", true);
GetNodeSignals().InitializeNode(dummyNode1.GetId(), &dummyNode1);
dummyNode1.nVersion = 1;
misbehave(dummyNode1.GetId(), 100);
Expand All @@ -104,7 +104,7 @@ BOOST_AUTO_TEST_CASE(DoS_bantime)
SetMockTime(nStartTime); // Overrides future calls to GetTime()

CAddress addr(ip(0xa0b0c001), NODE_NONE);
CNode dummyNode(id++, INVALID_SOCKET, addr, "", true);
CNode dummyNode(id++, NODE_NETWORK, INVALID_SOCKET, addr, "", true);
GetNodeSignals().InitializeNode(dummyNode.GetId(), &dummyNode);
dummyNode.nVersion = 1;

Expand Down
4 changes: 2 additions & 2 deletions src/test/net_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -165,12 +165,12 @@ BOOST_AUTO_TEST_CASE(cnode_simple_test)
bool fInboundIn = false;

// Test that fFeeler is false by default.
CNode* pnode1 = new CNode(id++, hSocket, addr, pszDest, fInboundIn);
CNode* pnode1 = new CNode(id++, NODE_NETWORK, hSocket, addr, pszDest, fInboundIn);
BOOST_CHECK(pnode1->fInbound == false);
BOOST_CHECK(pnode1->fFeeler == false);

fInboundIn = true;
CNode* pnode2 = new CNode(id++, hSocket, addr, pszDest, fInboundIn);
CNode* pnode2 = new CNode(id++, NODE_NETWORK, hSocket, addr, pszDest, fInboundIn);
BOOST_CHECK(pnode2->fInbound == true);
BOOST_CHECK(pnode2->fFeeler == false);
}
Expand Down

0 comments on commit 481929f

Please sign in to comment.