@ -36,6 +36,17 @@
# define MSG_NOSIGNAL 0
# define MSG_NOSIGNAL 0
# endif
# endif
// Fix for ancient MinGW versions, that don't have defined these in ws2tcpip.h.
// Todo: Can be removed when our pull-tester is upgraded to a modern MinGW version.
# ifdef WIN32
# ifndef PROTECTION_LEVEL_UNRESTRICTED
# define PROTECTION_LEVEL_UNRESTRICTED 10
# endif
# ifndef IPV6_PROTECTION_LEVEL
# define IPV6_PROTECTION_LEVEL 23
# endif
# endif
using namespace std ;
using namespace std ;
using namespace boost ;
using namespace boost ;
@ -816,7 +827,6 @@ void ThreadSocketHandler()
uiInterface . NotifyNumConnectionsChanged ( nPrevNodeCount ) ;
uiInterface . NotifyNumConnectionsChanged ( nPrevNodeCount ) ;
}
}
//
//
// Find which sockets have data to receive
// Find which sockets have data to receive
//
//
@ -838,6 +848,7 @@ void ThreadSocketHandler()
hSocketMax = max ( hSocketMax , hListenSocket ) ;
hSocketMax = max ( hSocketMax , hListenSocket ) ;
have_fds = true ;
have_fds = true ;
}
}
{
{
LOCK ( cs_vNodes ) ;
LOCK ( cs_vNodes ) ;
BOOST_FOREACH ( CNode * pnode , vNodes )
BOOST_FOREACH ( CNode * pnode , vNodes )
@ -898,58 +909,59 @@ void ThreadSocketHandler()
MilliSleep ( timeout . tv_usec / 1000 ) ;
MilliSleep ( timeout . tv_usec / 1000 ) ;
}
}
//
//
// Accept new connections
// Accept new connections
//
//
BOOST_FOREACH ( SOCKET hListenSocket , vhListenSocket )
BOOST_FOREACH ( SOCKET hListenSocket , vhListenSocket )
if ( hListenSocket ! = INVALID_SOCKET & & FD_ISSET ( hListenSocket , & fdsetRecv ) )
{
{
struct sockaddr_storage sockaddr ;
if ( hListenSocket ! = INVALID_SOCKET & & FD_ISSET ( hListenSocket , & fdsetRecv ) )
socklen_t len = sizeof ( sockaddr ) ;
SOCKET hSocket = accept ( hListenSocket , ( struct sockaddr * ) & sockaddr , & len ) ;
CAddress addr ;
int nInbound = 0 ;
if ( hSocket ! = INVALID_SOCKET )
if ( ! addr . SetSockAddr ( ( const struct sockaddr * ) & sockaddr ) )
LogPrintf ( " Warning: Unknown socket family \n " ) ;
{
{
LOCK ( cs_vNodes ) ;
struct sockaddr_storage sockaddr ;
BOOST_FOREACH ( CNode * pnode , vNodes )
socklen_t len = sizeof ( sockaddr ) ;
if ( pnode - > fInbound )
SOCKET hSocket = accept ( hListenSocket , ( struct sockaddr * ) & sockaddr , & len ) ;
nInbound + + ;
CAddress addr ;
}
int nInbound = 0 ;
if ( hSocket ! = INVALID_SOCKET )
if ( ! addr . SetSockAddr ( ( const struct sockaddr * ) & sockaddr ) )
LogPrintf ( " Warning: Unknown socket family \n " ) ;
if ( hSocket = = INVALID_SOCKET )
{
int nErr = WSAGetLastError ( ) ;
if ( nErr ! = WSAEWOULDBLOCK )
LogPrintf ( " socket error accept failed: %s \n " , NetworkErrorString ( nErr ) ) ;
}
else if ( nInbound > = nMaxConnections - MAX_OUTBOUND_CONNECTIONS )
{
closesocket ( hSocket ) ;
}
else if ( CNode : : IsBanned ( addr ) )
{
LogPrintf ( " connection from %s dropped (banned) \n " , addr . ToString ( ) ) ;
closesocket ( hSocket ) ;
}
else
{
LogPrint ( " net " , " accepted connection %s \n " , addr . ToString ( ) ) ;
CNode * pnode = new CNode ( hSocket , addr , " " , true ) ;
pnode - > AddRef ( ) ;
{
{
LOCK ( cs_vNodes ) ;
LOCK ( cs_vNodes ) ;
vNodes . push_back ( pnode ) ;
BOOST_FOREACH ( CNode * pnode , vNodes )
if ( pnode - > fInbound )
nInbound + + ;
}
if ( hSocket = = INVALID_SOCKET )
{
int nErr = WSAGetLastError ( ) ;
if ( nErr ! = WSAEWOULDBLOCK )
LogPrintf ( " socket error accept failed: %s \n " , NetworkErrorString ( nErr ) ) ;
}
else if ( nInbound > = nMaxConnections - MAX_OUTBOUND_CONNECTIONS )
{
closesocket ( hSocket ) ;
}
else if ( CNode : : IsBanned ( addr ) )
{
LogPrintf ( " connection from %s dropped (banned) \n " , addr . ToString ( ) ) ;
closesocket ( hSocket ) ;
}
else
{
LogPrint ( " net " , " accepted connection %s \n " , addr . ToString ( ) ) ;
CNode * pnode = new CNode ( hSocket , addr , " " , true ) ;
pnode - > AddRef ( ) ;
{
LOCK ( cs_vNodes ) ;
vNodes . push_back ( pnode ) ;
}
}
}
}
}
}
}
//
//
// Service each socket
// Service each socket
//
//
@ -1587,18 +1599,16 @@ bool BindListenPort(const CService &addrBind, string& strError)
return false ;
return false ;
}
}
# ifndef WIN32
# ifdef SO_NOSIGPIPE
# ifdef SO_NOSIGPIPE
// Different way of disabling SIGPIPE on BSD
// Different way of disabling SIGPIPE on BSD
setsockopt ( hListenSocket , SOL_SOCKET , SO_NOSIGPIPE , ( void * ) & nOne , sizeof ( int ) ) ;
setsockopt ( hListenSocket , SOL_SOCKET , SO_NOSIGPIPE , ( void * ) & nOne , sizeof ( int ) ) ;
# endif
# endif
# ifndef WIN32
// Allow binding if the port is still in TIME_WAIT state after
// Allow binding if the port is still in TIME_WAIT state after
// the program was closed and restarted. Not an issue on windows.
// the program was closed and restarted. Not an issue on windows!
setsockopt ( hListenSocket , SOL_SOCKET , SO_REUSEADDR , ( void * ) & nOne , sizeof ( int ) ) ;
setsockopt ( hListenSocket , SOL_SOCKET , SO_REUSEADDR , ( void * ) & nOne , sizeof ( int ) ) ;
# endif
# endif
# ifdef WIN32
# ifdef WIN32
// Set to non-blocking, incoming connections will also inherit this
// Set to non-blocking, incoming connections will also inherit this
if ( ioctlsocket ( hListenSocket , FIONBIO , ( u_long * ) & nOne ) = = SOCKET_ERROR )
if ( ioctlsocket ( hListenSocket , FIONBIO , ( u_long * ) & nOne ) = = SOCKET_ERROR )
@ -1622,10 +1632,8 @@ bool BindListenPort(const CService &addrBind, string& strError)
# endif
# endif
# endif
# endif
# ifdef WIN32
# ifdef WIN32
int nProtLevel = 10 /* PROTECTION_LEVEL_UNRESTRICTED */ ;
int nProtLevel = PROTECTION_LEVEL_UNRESTRICTED ;
int nParameterId = 23 /* IPV6_PROTECTION_LEVEl */ ;
setsockopt ( hListenSocket , IPPROTO_IPV6 , IPV6_PROTECTION_LEVEL , ( const char * ) & nProtLevel , sizeof ( int ) ) ;
// this call is allowed to fail
setsockopt ( hListenSocket , IPPROTO_IPV6 , nParameterId , ( const char * ) & nProtLevel , sizeof ( int ) ) ;
# endif
# endif
}
}