void CListenSocket::Process()
{
	m_OpenSocketsInterval = 0;
	POSITION pos2;
	for (POSITION pos1 = socket_list.GetHeadPosition(); (pos2 = pos1) != NULL; )
	{
		socket_list.GetNext(pos1);
		CClientReqSocket* cur_sock = socket_list.GetAt(pos2);
		if (cur_sock->IsDeleteThis())
		{
			if (cur_sock->IsValidSocket()){
				cur_sock->Close();			// calls 'closesocket'
			}
			else{
				cur_sock->Delete_Timed();	// may delete 'cur_sock'
			}
		}
		else{
			cur_sock->CheckTimeOut();		// may call 'shutdown'
		}
	}

	if ((GetOpenSockets() + 5 < thePrefs.GetMaxConnections() || CGlobalVariable::serverconnect->IsConnecting()) && !bListening)
		ReStartListening();
}
Example #2
0
void CListenSocket::Process()
{
	// 042e + Kry changes for Destroy
	m_OpenSocketsInterval = 0;
	SocketSet::iterator it = socket_list.begin();
	while ( it != socket_list.end() ) {
		CClientTCPSocket* cur_socket = *it++;
		if (!cur_socket->OnDestroy()) {
			if (cur_socket->ForDeletion()) {
				cur_socket->Destroy();
			} else {
				cur_socket->CheckTimeOut();
			}
		}
	}

	if ((GetOpenSockets()+5 < thePrefs::GetMaxConnections() || theApp->serverconnect->IsConnecting()) && !bListening) {
		ReStartListening();
	}
}
Example #3
0
void CListenSocket::OnAccept(int nErrorCode)
{
	// 0.42e
	if (!nErrorCode) {
		m_nPendingConnections++;
		if (m_nPendingConnections < 1) {
			wxFAIL;
			m_nPendingConnections = 1;
		}
		if (TooManySockets(true) && !theApp->serverconnect->IsConnecting()) {
			StopListening();
			return;
		} else if (bListening == false) {
			// If the client is still at maxconnections,
			// this will allow it to go above it ...
			// But if you don't, you will get a lowID on all servers.
			ReStartListening();
		}
		// Deal with the pending connections, there might be more than one, due to
		// the StopListening() call above.
		while (m_nPendingConnections) {
			m_nPendingConnections--;
			// Create a new socket to deal with the connection
			CClientTCPSocket* newclient = new CClientTCPSocket();
			// Accept the connection and give it to the newly created socket
			if (!AcceptWith(*newclient, false)) {
				newclient->Safe_Delete();
			} else {
				wxASSERT(theApp->IsRunning());
				if (!newclient->InitNetworkData()) {
					// IP or port were not returned correctly
					// from the accepted address, or filtered.
					newclient->Safe_Delete();
				}
			}
		}
	}
}
void CListenSocket::OnAccept(int nErrorCode)
{
	if (!nErrorCode)
	{
		m_nPendingConnections++;
		if (m_nPendingConnections < 1){
			ASSERT(0);
			m_nPendingConnections = 1;
		}

		if (TooManySockets(true) && !CGlobalVariable::serverconnect->IsConnecting()){
			StopListening();
			return;
		}
		else if (!bListening)
			ReStartListening(); //If the client is still at maxconnections, this will allow it to go above it.. But if you don't, you will get a lowID on all servers.

		uint32 nFataErrors = 0;
		while (m_nPendingConnections > 0)
		{
			m_nPendingConnections--;

			CClientReqSocket* newclient;
			SOCKADDR_IN SockAddr = {0};
			int iSockAddrLen = sizeof SockAddr;
			if (thePrefs.GetConditionalTCPAccept() && !thePrefs.GetProxySettings().UseProxy)
			{
				_iAcceptConnectionCondRejected = 0;
				SOCKET sNew = WSAAccept(m_SocketData.hSocket, (SOCKADDR*)&SockAddr, &iSockAddrLen, AcceptConnectionCond, 0);
				if (sNew == INVALID_SOCKET){
					DWORD nError = GetLastError();
					if (nError == WSAEWOULDBLOCK){
						DebugLogError(LOG_STATUSBAR, _T("%hs: Backlogcounter says %u connections waiting, Accept() says WSAEWOULDBLOCK - setting counter to zero!"), __FUNCTION__, m_nPendingConnections);
						m_nPendingConnections = 0;
						break;
					}
					else{
						if (nError != WSAECONNREFUSED || _iAcceptConnectionCondRejected == 0){
							DebugLogError(LOG_STATUSBAR, _T("%hs: Backlogcounter says %u connections waiting, Accept() says %s - setting counter to zero!"), __FUNCTION__, m_nPendingConnections, GetErrorMessage(nError, 1));
							nFataErrors++;
						}
						else if (_iAcceptConnectionCondRejected == 1)
							theStats.filteredclients++;
					}
					if (nFataErrors > 10){
						// the question is what todo on a error. We cant just ignore it because then the backlog will fill up
						// and lock everything. We can also just endlos try to repeat it because this will lock up eMule
						// this should basically never happen anyway
						// however if we are in such a position, try to reinitalize the socket.
						DebugLogError(LOG_STATUSBAR, _T("%hs: Accept() Error Loop, recreating socket"), __FUNCTION__);
						Close();
						StartListening();
						m_nPendingConnections = 0;
						break;
					}
					continue;
				}
				newclient = new CClientReqSocket;
				VERIFY( newclient->InitAsyncSocketExInstance() );
				newclient->m_SocketData.hSocket = sNew;
				newclient->AttachHandle(sNew);

				AddConnection();
			}
			else
			{
				newclient = new CClientReqSocket;
				if (!Accept(*newclient, (SOCKADDR*)&SockAddr, &iSockAddrLen)){
					newclient->Safe_Delete();
					DWORD nError = GetLastError();
					if (nError == WSAEWOULDBLOCK){
						DebugLogError(LOG_STATUSBAR, _T("%hs: Backlogcounter says %u connections waiting, Accept() says WSAEWOULDBLOCK - setting counter to zero!"), __FUNCTION__, m_nPendingConnections);
						m_nPendingConnections = 0;
						break;
					}
					else{
						DebugLogError(LOG_STATUSBAR, _T("%hs: Backlogcounter says %u connections waiting, Accept() says %s - setting counter to zero!"), __FUNCTION__, m_nPendingConnections, GetErrorMessage(nError, 1));
						nFataErrors++;
					}
					if (nFataErrors > 10){
						// the question is what todo on a error. We cant just ignore it because then the backlog will fill up
						// and lock everything. We can also just endlos try to repeat it because this will lock up eMule
						// this should basically never happen anyway
						// however if we are in such a position, try to reinitalize the socket.
						DebugLogError(LOG_STATUSBAR, _T("%hs: Accept() Error Loop, recreating socket"), __FUNCTION__);
						Close();
						StartListening();
						m_nPendingConnections = 0;
						break;
					}
					continue;
				}

				AddConnection();

				if (SockAddr.sin_addr.S_un.S_addr == 0) // for safety..
				{
					iSockAddrLen = sizeof SockAddr;
					newclient->GetPeerName((SOCKADDR*)&SockAddr, &iSockAddrLen);
					DebugLogWarning(_T("SockAddr.sin_addr.S_un.S_addr == 0;  GetPeerName returned %s"), ipstr(SockAddr.sin_addr.S_un.S_addr));
				}

				ASSERT( SockAddr.sin_addr.S_un.S_addr != 0 && SockAddr.sin_addr.S_un.S_addr != INADDR_NONE );

				if (CGlobalVariable::ipfilter->IsFiltered(SockAddr.sin_addr.S_un.S_addr)){
					if (thePrefs.GetLogFilteredIPs())
						AddDebugLogLine(false, _T("Rejecting connection attempt (IP=%s) - IP filter (%s)"), ipstr(SockAddr.sin_addr.S_un.S_addr), CGlobalVariable::ipfilter->GetLastHit());
					newclient->Safe_Delete();
					theStats.filteredclients++;
					continue;
				}

				if (CGlobalVariable::clientlist->IsBannedClient(SockAddr.sin_addr.S_un.S_addr)){
					if (thePrefs.GetLogBannedClients()){
						CUpDownClient* pClient = CGlobalVariable::clientlist->FindClientByIP(SockAddr.sin_addr.S_un.S_addr);
						AddDebugLogLine(false, _T("Rejecting connection attempt of banned client %s %s"), ipstr(SockAddr.sin_addr.S_un.S_addr), pClient->DbgGetClientInfo());
					}
					newclient->Safe_Delete();
					continue;
				}
			}
			newclient->AsyncSelect(FD_WRITE | FD_READ | FD_CLOSE);
		}

		ASSERT( m_nPendingConnections >= 0 );
	}
}