@ -50,7 +50,16 @@
using namespace std ;
using namespace std ;
using namespace boost ;
using namespace boost ;
static const int MAX_OUTBOUND_CONNECTIONS = 8 ;
namespace {
const int MAX_OUTBOUND_CONNECTIONS = 8 ;
struct ListenSocket {
SOCKET socket ;
bool whitelisted ;
ListenSocket ( SOCKET socket , bool whitelisted ) : socket ( socket ) , whitelisted ( whitelisted ) { }
} ;
}
//
//
// Global state variables
// Global state variables
@ -65,7 +74,7 @@ static bool vfLimited[NET_MAX] = {};
static CNode * pnodeLocalHost = NULL ;
static CNode * pnodeLocalHost = NULL ;
static CNode * pnodeSync = NULL ;
static CNode * pnodeSync = NULL ;
uint64_t nLocalHostNonce = 0 ;
uint64_t nLocalHostNonce = 0 ;
static std : : vector < SOCKET > vhListenSocket ;
static std : : vector < ListenSocket > vhListenSocket ;
CAddrMan addrman ;
CAddrMan addrman ;
int nMaxConnections = 125 ;
int nMaxConnections = 125 ;
@ -593,6 +602,24 @@ bool CNode::Ban(const CNetAddr &addr) {
return true ;
return true ;
}
}
std : : vector < CSubNet > CNode : : vWhitelistedRange ;
CCriticalSection CNode : : cs_vWhitelistedRange ;
bool CNode : : IsWhitelistedRange ( const CNetAddr & addr ) {
LOCK ( cs_vWhitelistedRange ) ;
BOOST_FOREACH ( const CSubNet & subnet , vWhitelistedRange ) {
if ( subnet . Match ( addr ) )
return true ;
}
return false ;
}
void CNode : : AddWhitelistedRange ( const CSubNet & subnet ) {
LOCK ( cs_vWhitelistedRange ) ;
vWhitelistedRange . push_back ( subnet ) ;
}
# undef X
# undef X
# define X(name) stats.name = name
# define X(name) stats.name = name
void CNode : : copyStats ( CNodeStats & stats )
void CNode : : copyStats ( CNodeStats & stats )
@ -609,6 +636,7 @@ void CNode::copyStats(CNodeStats &stats)
X ( nStartingHeight ) ;
X ( nStartingHeight ) ;
X ( nSendBytes ) ;
X ( nSendBytes ) ;
X ( nRecvBytes ) ;
X ( nRecvBytes ) ;
X ( fWhitelisted ) ;
stats . fSyncNode = ( this = = pnodeSync ) ;
stats . fSyncNode = ( this = = pnodeSync ) ;
// It is common for nodes with good ping times to suddenly become lagged,
// It is common for nodes with good ping times to suddenly become lagged,
@ -848,9 +876,9 @@ void ThreadSocketHandler()
SOCKET hSocketMax = 0 ;
SOCKET hSocketMax = 0 ;
bool have_fds = false ;
bool have_fds = false ;
BOOST_FOREACH ( SOCKET hListenSocket , vhListenSocket ) {
BOOST_FOREACH ( const ListenSocket & hListenSocket , vhListenSocket ) {
FD_SET ( hListenSocket , & fdsetRecv ) ;
FD_SET ( hListenSocket . socket , & fdsetRecv ) ;
hSocketMax = max ( hSocketMax , hListenSocket ) ;
hSocketMax = max ( hSocketMax , hListenSocket . socket ) ;
have_fds = true ;
have_fds = true ;
}
}
@ -917,13 +945,13 @@ void ThreadSocketHandler()
//
//
// Accept new connections
// Accept new connections
//
//
BOOST_FOREACH ( SOCKET hListenSocket , vhListenSocket )
BOOST_FOREACH ( const ListenSocket & hListenSocket , vhListenSocket )
{
{
if ( hListenSocket ! = INVALID_SOCKET & & FD_ISSET ( hListenSocket , & fdsetRecv ) )
if ( hListenSocket . socket ! = INVALID_SOCKET & & FD_ISSET ( hListenSocket . s ocket , & fdsetRecv ) )
{
{
struct sockaddr_storage sockaddr ;
struct sockaddr_storage sockaddr ;
socklen_t len = sizeof ( sockaddr ) ;
socklen_t len = sizeof ( sockaddr ) ;
SOCKET hSocket = accept ( hListenSocket , ( struct sockaddr * ) & sockaddr , & len ) ;
SOCKET hSocket = accept ( hListenSocket . socket , ( struct sockaddr * ) & sockaddr , & len ) ;
CAddress addr ;
CAddress addr ;
int nInbound = 0 ;
int nInbound = 0 ;
@ -931,6 +959,7 @@ void ThreadSocketHandler()
if ( ! addr . SetSockAddr ( ( const struct sockaddr * ) & sockaddr ) )
if ( ! addr . SetSockAddr ( ( const struct sockaddr * ) & sockaddr ) )
LogPrintf ( " Warning: Unknown socket family \n " ) ;
LogPrintf ( " Warning: Unknown socket family \n " ) ;
bool whitelisted = hListenSocket . whitelisted | | CNode : : IsWhitelistedRange ( addr ) ;
{
{
LOCK ( cs_vNodes ) ;
LOCK ( cs_vNodes ) ;
BOOST_FOREACH ( CNode * pnode , vNodes )
BOOST_FOREACH ( CNode * pnode , vNodes )
@ -948,7 +977,7 @@ void ThreadSocketHandler()
{
{
closesocket ( hSocket ) ;
closesocket ( hSocket ) ;
}
}
else if ( CNode : : IsBanned ( addr ) )
else if ( CNode : : IsBanned ( addr ) & & ! whitelisted )
{
{
LogPrintf ( " connection from %s dropped (banned) \n " , addr . ToString ( ) ) ;
LogPrintf ( " connection from %s dropped (banned) \n " , addr . ToString ( ) ) ;
closesocket ( hSocket ) ;
closesocket ( hSocket ) ;
@ -957,6 +986,7 @@ void ThreadSocketHandler()
{
{
CNode * pnode = new CNode ( hSocket , addr , " " , true ) ;
CNode * pnode = new CNode ( hSocket , addr , " " , true ) ;
pnode - > AddRef ( ) ;
pnode - > AddRef ( ) ;
pnode - > fWhitelisted = whitelisted ;
{
{
LOCK ( cs_vNodes ) ;
LOCK ( cs_vNodes ) ;
@ -1580,7 +1610,7 @@ void ThreadMessageHandler()
bool BindListenPort ( const CService & addrBind , string & strError )
bool BindListenPort ( const CService & addrBind , string & strError , bool fWhitelisted )
{
{
strError = " " ;
strError = " " ;
int nOne = 1 ;
int nOne = 1 ;
@ -1661,9 +1691,9 @@ bool BindListenPort(const CService &addrBind, string& strError)
return false ;
return false ;
}
}
vhListenSocket . push_back ( hListenSocket ) ;
vhListenSocket . push_back ( ListenSocket ( hListenSocket , fWhitelisted ) ) ;
if ( addrBind . IsRoutable ( ) & & fDiscover )
if ( addrBind . IsRoutable ( ) & & fDiscover & & ! fWhitelisted )
AddLocal ( addrBind , LOCAL_BIND ) ;
AddLocal ( addrBind , LOCAL_BIND ) ;
return true ;
return true ;
@ -1788,9 +1818,9 @@ public:
BOOST_FOREACH ( CNode * pnode , vNodes )
BOOST_FOREACH ( CNode * pnode , vNodes )
if ( pnode - > hSocket ! = INVALID_SOCKET )
if ( pnode - > hSocket ! = INVALID_SOCKET )
closesocket ( pnode - > hSocket ) ;
closesocket ( pnode - > hSocket ) ;
BOOST_FOREACH ( SOCKET hListenSocket , vhListenSocket )
BOOST_FOREACH ( ListenSocket & hListenSocket , vhListenSocket )
if ( hListenSocket ! = INVALID_SOCKET )
if ( hListenSocket . socket ! = INVALID_SOCKET )
if ( closesocket ( hListenSocket ) = = SOCKET_ERROR )
if ( closesocket ( hListenSocket . socket ) = = SOCKET_ERROR )
LogPrintf ( " closesocket(hListenSocket) failed with error %s \n " , NetworkErrorString ( WSAGetLastError ( ) ) ) ;
LogPrintf ( " closesocket(hListenSocket) failed with error %s \n " , NetworkErrorString ( WSAGetLastError ( ) ) ) ;
// clean up some globals (to help leak detection)
// clean up some globals (to help leak detection)