5050using namespace std ;
5151using namespace boost ;
5252
53- static const int MAX_OUTBOUND_CONNECTIONS = 8 ;
53+ namespace {
54+ const int MAX_OUTBOUND_CONNECTIONS = 8 ;
55+
56+ struct ListenSocket {
57+ SOCKET socket;
58+ bool whitelisted;
59+
60+ ListenSocket (SOCKET socket, bool whitelisted) : socket(socket), whitelisted(whitelisted) {}
61+ };
62+ }
5463
5564//
5665// Global state variables
@@ -65,7 +74,7 @@ static bool vfLimited[NET_MAX] = {};
6574static CNode* pnodeLocalHost = NULL ;
6675static CNode* pnodeSync = NULL ;
6776uint64_t nLocalHostNonce = 0 ;
68- static std::vector<SOCKET > vhListenSocket;
77+ static std::vector<ListenSocket > vhListenSocket;
6978CAddrMan addrman;
7079int nMaxConnections = 125 ;
7180
@@ -593,6 +602,24 @@ bool CNode::Ban(const CNetAddr &addr) {
593602 return true ;
594603}
595604
605+
606+ std::vector<CSubNet> CNode::vWhitelistedRange;
607+ CCriticalSection CNode::cs_vWhitelistedRange;
608+
609+ bool CNode::IsWhitelistedRange (const CNetAddr &addr) {
610+ LOCK (cs_vWhitelistedRange);
611+ BOOST_FOREACH (const CSubNet& subnet, vWhitelistedRange) {
612+ if (subnet.Match (addr))
613+ return true ;
614+ }
615+ return false ;
616+ }
617+
618+ void CNode::AddWhitelistedRange (const CSubNet &subnet) {
619+ LOCK (cs_vWhitelistedRange);
620+ vWhitelistedRange.push_back (subnet);
621+ }
622+
596623#undef X
597624#define X (name ) stats.name = name
598625void CNode::copyStats (CNodeStats &stats)
@@ -609,6 +636,7 @@ void CNode::copyStats(CNodeStats &stats)
609636 X (nStartingHeight);
610637 X (nSendBytes);
611638 X (nRecvBytes);
639+ X (fWhitelisted );
612640 stats.fSyncNode = (this == pnodeSync);
613641
614642 // It is common for nodes with good ping times to suddenly become lagged,
@@ -848,9 +876,9 @@ void ThreadSocketHandler()
848876 SOCKET hSocketMax = 0 ;
849877 bool have_fds = false ;
850878
851- BOOST_FOREACH (SOCKET hListenSocket, vhListenSocket) {
852- FD_SET (hListenSocket, &fdsetRecv);
853- hSocketMax = max (hSocketMax, hListenSocket);
879+ BOOST_FOREACH (const ListenSocket& hListenSocket, vhListenSocket) {
880+ FD_SET (hListenSocket. socket , &fdsetRecv);
881+ hSocketMax = max (hSocketMax, hListenSocket. socket );
854882 have_fds = true ;
855883 }
856884
@@ -917,20 +945,21 @@ void ThreadSocketHandler()
917945 //
918946 // Accept new connections
919947 //
920- BOOST_FOREACH (SOCKET hListenSocket, vhListenSocket)
948+ BOOST_FOREACH (const ListenSocket& hListenSocket, vhListenSocket)
921949 {
922- if (hListenSocket != INVALID_SOCKET && FD_ISSET (hListenSocket, &fdsetRecv))
950+ if (hListenSocket. socket != INVALID_SOCKET && FD_ISSET (hListenSocket. socket , &fdsetRecv))
923951 {
924952 struct sockaddr_storage sockaddr;
925953 socklen_t len = sizeof (sockaddr);
926- SOCKET hSocket = accept (hListenSocket, (struct sockaddr *)&sockaddr, &len);
954+ SOCKET hSocket = accept (hListenSocket. socket , (struct sockaddr *)&sockaddr, &len);
927955 CAddress addr;
928956 int nInbound = 0 ;
929957
930958 if (hSocket != INVALID_SOCKET)
931959 if (!addr.SetSockAddr ((const struct sockaddr *)&sockaddr))
932960 LogPrintf (" Warning: Unknown socket family\n " );
933961
962+ bool whitelisted = hListenSocket.whitelisted || CNode::IsWhitelistedRange (addr);
934963 {
935964 LOCK (cs_vNodes);
936965 BOOST_FOREACH (CNode* pnode, vNodes)
@@ -948,7 +977,7 @@ void ThreadSocketHandler()
948977 {
949978 closesocket (hSocket);
950979 }
951- else if (CNode::IsBanned (addr))
980+ else if (CNode::IsBanned (addr) && !whitelisted )
952981 {
953982 LogPrintf (" connection from %s dropped (banned)\n " , addr.ToString ());
954983 closesocket (hSocket);
@@ -957,6 +986,7 @@ void ThreadSocketHandler()
957986 {
958987 CNode* pnode = new CNode (hSocket, addr, " " , true );
959988 pnode->AddRef ();
989+ pnode->fWhitelisted = whitelisted;
960990
961991 {
962992 LOCK (cs_vNodes);
@@ -1580,7 +1610,7 @@ void ThreadMessageHandler()
15801610
15811611
15821612
1583- bool BindListenPort (const CService &addrBind, string& strError)
1613+ bool BindListenPort (const CService &addrBind, string& strError, bool fWhitelisted )
15841614{
15851615 strError = " " ;
15861616 int nOne = 1 ;
@@ -1661,9 +1691,9 @@ bool BindListenPort(const CService &addrBind, string& strError)
16611691 return false ;
16621692 }
16631693
1664- vhListenSocket.push_back (hListenSocket);
1694+ vhListenSocket.push_back (ListenSocket ( hListenSocket, fWhitelisted ) );
16651695
1666- if (addrBind.IsRoutable () && fDiscover )
1696+ if (addrBind.IsRoutable () && fDiscover && ! fWhitelisted )
16671697 AddLocal (addrBind, LOCAL_BIND);
16681698
16691699 return true ;
@@ -1788,9 +1818,9 @@ class CNetCleanup
17881818 BOOST_FOREACH (CNode* pnode, vNodes)
17891819 if (pnode->hSocket != INVALID_SOCKET)
17901820 closesocket (pnode->hSocket );
1791- BOOST_FOREACH (SOCKET hListenSocket, vhListenSocket)
1792- if (hListenSocket != INVALID_SOCKET)
1793- if (closesocket (hListenSocket) == SOCKET_ERROR)
1821+ BOOST_FOREACH (ListenSocket& hListenSocket, vhListenSocket)
1822+ if (hListenSocket. socket != INVALID_SOCKET)
1823+ if (closesocket (hListenSocket. socket ) == SOCKET_ERROR)
17941824 LogPrintf (" closesocket(hListenSocket) failed with error %s\n " , NetworkErrorString (WSAGetLastError ()));
17951825
17961826 // clean up some globals (to help leak detection)
0 commit comments