void CTraverseBySourceExchange::OnRecvSync(const uchar * data, int /*len*/, DWORD /*ip*/, WORD /*port*/)
{
	TRACE("Receive NAT Sync Request From Source Exchange!\n");

	//UINT realsize=len-1;// VC-linhai[2007-08-06]:warning C4189: “realsize” : 局部变量已初始化但不引用
	const uchar * realdata=data+1;

	DWORD cip = *(DWORD*)(realdata);
	WORD cport = *(WORD*)(realdata+4);

	if(cip==0 || cport==0)
	{
		return;
	}
	const uchar * id=realdata+6;

	DWORD ConnAck = 0;
	memcpy(&ConnAck, id+16, 4);

	TRACE("recv sync, ConnAck=%08x\n", ConnAck);
#ifdef _DEBUG
	in_addr addr;
	addr.s_addr = cip;
	TRACE("peer addr of %02X%02X%02X%02X = %s:%d\n", id[0], id[1], id[2],id[3],
		inet_ntoa(addr), ntohs(cport));
#endif
	uchar myid[16];
	GetMyUserHash(myid);
	if(memcmp(id, myid, 16)==0)
	{
		_AddLogLine(false, _T("ERROR: recv myself for traversal"));
		return;
	}

	CAsyncSocketEx * pASock=NULL;
	CUpDownClient * pClient= CGlobalVariable::clientlist->FindClientByUserHash(id);
	if(pClient)
	{
		pASock = pClient->socket;

		if(! pASock)
		{
			CRuntimeClass * pClassSocket = RUNTIME_CLASS(CClientReqSocket);
			CClientReqSocket * socket = static_cast<CClientReqSocket*>(pClassSocket->CreateObject());
			socket->SetClient(pClient);
			if (!socket->Create())
			{
				socket->Safe_Delete();
				return;
			}

			pClient->socket = socket;
			pASock = socket;
		}
		ASSERT(pASock);
		if(! pASock) 
		{
			return;
		}
	}
	else
	{
		TRACE("\n->%s: Accept a incoming sock for %02X%02X%02X%02X\n", __FUNCTION__,
			id[0],id[1],id[2],id[3]);

		pASock = CGlobalVariable::natthread->GetTempASock(id);
	}

	m_dwClientIp = cip;
	m_wClientPort = cport;

	m_dwState |=NAT_S_SYNC;
	SendPingPacket();
}
Пример #2
0
CAsyncSocketEx * CListenSocket::OnAcceptEx(int /*nErrorCode*/)
{
	/*	m_nPendingConnections++;
	if (m_nPendingConnections < 1){
	ASSERT(0);
	m_nPendingConnections = 1;
	}

	if (TooManySockets(true) && !CGlobalVariable::serverconnect->IsConnecting()){
	StopListening();
	return NULL;
	}
	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)
	//{
	if(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 = 100;
		/*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;
		newclient->m_bUseNat = true;

		VERIFY( newclient->InitAsyncSocketExInstance() );
		//newclient->m_SocketData.hSocket = sNew;
		//newclient->AttachHandle(sNew);

		AddConnection();
	}
	else
	{
		newclient = new CClientReqSocket;
		newclient->m_bUseNat = true;

		//SOCKET sNew = 100;
		//newclient->m_SocketData.hSocket = sNew;

		/*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);

	return newclient;
	//}

	//ASSERT( m_nPendingConnections >= 0 );
}