Пример #1
0
void CHttpClientReqSocket::DataReceived(const BYTE* pucData, UINT uSize)
{
	bool bResult = false;
	CString strError;
	
	try
	{
		bResult = ProcessHttpPacket(pucData, uSize);
	}
	catch(CMemoryException* ex)
	{
		strError.Format(_T("Error: HTTP socket: Memory exception; %s"), DbgGetClientInfo());
		if (thePrefs.GetVerbose())
			AddDebugLogLine(false, _T("%s"), strError);
		ex->Delete();
	}
	catch(CFileException* ex)
	{
		TCHAR szError[MAX_CFEXP_ERRORMSG];
		ex->GetErrorMessage(szError, ARRSIZE(szError));
		strError.Format(_T("Error: HTTP socket: File exception - %s"), szError);
		if (thePrefs.GetVerbose())
			AddDebugLogLine(false, _T("%s"), strError);
		ex->Delete();
	}
	catch(CString ex)
	{
		strError.Format(_T("Error: HTTP socket: %s; %s"), ex, DbgGetClientInfo());
		if (thePrefs.GetVerbose())
			AddDebugLogLine(false, _T("%s"), strError);
	}

	if (!bResult && !IsDeleteThis())
	{
		if (thePrefs.GetVerbose() && thePrefs.GetDebugClientTCPLevel() <= 0)
		{
			for (int i = 0; i < m_astrHttpHeaders.GetCount(); i++)
				AddDebugLogLine(false, _T("<%hs"), m_astrHttpHeaders.GetAt(i));
		}

		// In case this socket is attached to an CHttpClient, we are dealing with the real CUpDownClient here
		// In case this socket is a PeerCacheUp/Down socket, we are dealing with the attached CUpDownClient here
		//if (GetClient())
		//	GetClient()->SetDownloadState(DS_ERROR);
		if (client)	// NOTE: The usage of 'client' and 'GetClient' makes quite a difference here!
			client->SetDownloadState(DS_ERROR);

		if (strError.IsEmpty())
			strError = _T("Error: HTTP socket");

		// In case this socket is attached to an CHttpClient, we are disconnecting the real CUpDownClient here
		// In case this socket is a PeerCacheUp/Down socket, we are not disconnecting the attached CUpDownClient here
		// PC-TODO: This needs to be cleaned up thoroughly because that client dependency is somewhat hidden in the
		// usage of CClientReqSocket::client and CHttpClientReqSocket::GetClient.
		Disconnect(strError);
	}
}
Пример #2
0
bool CUpDownClient::ProcessPeerCacheAcknowledge(const uchar* packet, UINT size)
{
	const bool bDebug = (thePrefs.GetDebugClientTCPLevel() > 0);
	if (bDebug)
		DebugRecv("OP_PeerCacheAck", this);

	if (socket == NULL){
		ASSERT(0);
		return false;
	}

	m_bPeerCacheUpHit = false;
	CSafeMemFile data(packet, size);
	UINT uAck = data.ReadUInt8();
	if (uAck == 1)
	{
		// Cache hit
		if (bDebug)
			Debug(_T("  Cache hit\n"));

		// PC-TODO: If this socket is closed, PeerCache also closes the socket which it had opened to the
		// remote client! So, to give the remote client a chance to receive all the data from the PeerCache,
		// we have to keep this socket open, although it's not needed nor could it be reused!
		if (m_pPCUpSocket == NULL){
			if (thePrefs.GetVerbose())
				DebugLogError(_T("PeerCacheAck received - missing socket; %s"), DbgGetClientInfo());
			ASSERT(0);
			return false;
		}
//		m_pPCUpSocket->Safe_Delete();
//		m_pPCUpSocket = NULL;
		m_pPCUpSocket->SetTimeOut(MIN2MS(60)); // set socket timeout to 1 hour ??
		m_bPeerCacheUpHit = true;
	}
	else if (uAck == 0)
	{
		// Cache miss, keep uploading
		if (bDebug)
			Debug(_T("  Cache miss\n"));
	}
	else{
		ASSERT(0);
		return false;
	}

	// PC-TODO: Since we can not close the PC socket, what exactly do we need this ACK-packet for?
	;

	UpdateDisplayedInfo();

	return true;
}
Пример #3
0
bool CUpDownClient::ProcessPeerCacheAnswer(const uchar* packet, UINT size)
{
	const bool bDebug = (thePrefs.GetDebugClientTCPLevel() > 0);
	ASSERT( GetDownloadState() == DS_DOWNLOADING );
	ASSERT( m_ePeerCacheDownState == PCDS_WAIT_CLIENT_REPLY );

	if (bDebug)
		DebugRecv("OP_PeerCacheAnswer", this);

	if (socket == NULL || reqfile == NULL){
		ASSERT(0);
		return false;
	}

	CSafeMemFile dataRecv(packet, size);
	uint8 uPCVersion = dataRecv.ReadUInt8();
	if (uPCVersion != PCPCK_VERSION){
		if (bDebug)
			Debug(_T("  ***Invalid packet version: 0x%02x\n"), uPCVersion);
		ASSERT(0);
		return false;
	}
	uint8 uPCOpcode = dataRecv.ReadUInt8();
	if (uPCOpcode == PCOP_NONE){
		if (thePrefs.GetVerbose())
			AddDebugLogLine(false, _T("Client does not support PeerCache; %s"), DbgGetClientInfo());
		return false;
	}
	if (uPCOpcode != PCOP_RES){
		if (bDebug)
			Debug(_T("  ***Invalid packet opcode: 0x%02x\n"), uPCOpcode);
		ASSERT(0);
		return false;
	}

	uint32 uPushId = 0;
	uint32 uRemoteIP = 0;
	uchar aucFileHash[16];
	md4clr(aucFileHash);

	CString strInfo;
	UINT uTags = dataRecv.ReadUInt8();
	while (uTags--)
	{
		CTag tag(&dataRecv, GetUnicodeSupport()!=utf8strNone);
		if (tag.GetNameID() == PCTAG_PUSHID && tag.IsInt())
		{
			uPushId = tag.GetInt();
			if (bDebug)
				strInfo.AppendFormat(_T("  PushId=%u"), uPushId);
		}
		else if (tag.GetNameID() == PCTAG_PUBLICIP && tag.IsInt())
		{
			uRemoteIP = tag.GetInt();
			if (bDebug)
				strInfo.AppendFormat(_T("  RemoteIP=%s"), ipstr(uRemoteIP));
		}
		else if (tag.GetNameID() == PCTAG_FILEID && tag.IsHash() && tag.GetHash() != NULL)
		{
			md4cpy(aucFileHash, tag.GetHash());
			if (bDebug)
				strInfo.AppendFormat(_T("  FileId=%s"), md4str(aucFileHash));
		}
		else
		{
			if (bDebug)
				strInfo.AppendFormat(_T("  ***UnkTag: %s"), tag.GetFullInfo());
			ASSERT(0);
		}
	}

	if (bDebug)
	{
		if (dataRecv.GetPosition() < dataRecv.GetLength())
			strInfo.AppendFormat(_T("  ***AddData: %u bytes"), (UINT)(dataRecv.GetLength() - dataRecv.GetPosition()));
		Debug(_T("%s\n"), strInfo);
	}

	if (uPushId == 0 || uRemoteIP == 0 || isnulmd4(aucFileHash)){
		if (thePrefs.GetVerbose())
			AddDebugLogLine(false, _T("Invalid PeerCacheAnswer; %s"), DbgGetClientInfo());
		return false;
	}

	if (md4cmp(aucFileHash, reqfile->GetFileHash()) != 0){
		if (thePrefs.GetVerbose())
			AddDebugLogLine(false, _T("PeerCacheAnswer reqfile does not match ed2k reqfile; %s"), DbgGetClientInfo());
		return false;
	}

	m_uPeerCacheDownloadPushId = uPushId;
	m_uPeerCacheRemoteIP = uRemoteIP;

	if (!SendHttpBlockRequests())
		return false;

	theApp.m_pPeerCache->DownloadAttemptStarted();
	ASSERT( m_ePeerCacheDownState == PCDS_WAIT_CACHE_REPLY );
	return true;
}
Пример #4
0
bool CUpDownClient::ProcessPeerCacheQuery(const uchar* packet, UINT size)
{
	const bool bDebug = (thePrefs.GetDebugClientTCPLevel() > 0);
	if (bDebug)
		DebugRecv("OP_PeerCacheQuery", this);

	if (socket == NULL){
		ASSERT(0);
		return false;
	}

	CSafeMemFile dataRecv(packet, size);
	uint8 uPCVersion = dataRecv.ReadUInt8();
	if (uPCVersion != PCPCK_VERSION){
		if (bDebug)
			Debug(_T("   ***Invalid packet version: 0x%02x\n"), uPCVersion);
		ASSERT(0);
		return false;
	}
	uint8 uPCOpcode = dataRecv.ReadUInt8();
	if (uPCOpcode != PCOP_REQ){
		if (bDebug)
			Debug(_T("   ***Invalid packet opcode: 0x%02x\n"), uPCOpcode);
		ASSERT(0);
		return false;
	}

	uint32 uCacheIP = 0;
	uint16 uCachePort = 0;
	uint32 uPushId = 0;
	uchar aucFileHash[16];
	uint32 uRemoteIP = 0;
	md4clr(aucFileHash);

	CString strInfo;
	UINT uTags = dataRecv.ReadUInt8();
	while (uTags--)
	{
		CTag tag(&dataRecv, GetUnicodeSupport()!=utf8strNone);
		if (tag.GetNameID() == PCTAG_CACHEIP && tag.IsInt())
		{
			uCacheIP = tag.GetInt();
			if (bDebug)
				strInfo.AppendFormat(_T("  CacheIP=%s"), ipstr(uCacheIP));
		}
		else if (tag.GetNameID() == PCTAG_CACHEPORT && tag.IsInt())
		{
			uCachePort = (uint16)tag.GetInt();
			if (bDebug)
				strInfo.AppendFormat(_T("  CachePort=%u"), uCachePort);
		}
		else if (tag.GetNameID() == PCTAG_PUSHID && tag.IsInt())
		{
			uPushId = tag.GetInt();
			if (bDebug)
				strInfo.AppendFormat(_T("  PushId=%u"), uPushId);
		}
		else if (tag.GetNameID() == PCTAG_FILEID && tag.IsHash() && tag.GetHash() != NULL)
		{
			md4cpy(aucFileHash, tag.GetHash());
			if (bDebug)
				strInfo.AppendFormat(_T("  FileId=%s"), md4str(aucFileHash));
		}
		else if (tag.GetNameID() == PCTAG_PUBLICIP && tag.IsInt())
		{
			uRemoteIP = tag.GetInt();
			if (bDebug)
				strInfo.AppendFormat(_T("  PublicIP=%s"), ipstr(uRemoteIP));
		}
		else
		{
			if (bDebug)
				strInfo.AppendFormat(_T("  ***UnkTag: %s"), tag.GetFullInfo());
			ASSERT(0);
		}
	}

	if (bDebug)
	{
		if (dataRecv.GetPosition() < dataRecv.GetLength())
			strInfo.AppendFormat(_T("  ***AddData: %u bytes"), (UINT)(dataRecv.GetLength() - dataRecv.GetPosition()));
		Debug(_T("%s\n"), strInfo);
	}

	if (uCacheIP == 0 || uCachePort == 0 || uPushId == 0 || isnulmd4(aucFileHash)){
		if (thePrefs.GetVerbose())
			AddDebugLogLine(false, _T("Invalid PeerCacheQuery; %s"), DbgGetClientInfo());
		return false;
	}

	CKnownFile* pUploadFile = theApp.sharedfiles->GetFileByID(aucFileHash);
	if (pUploadFile == NULL){
		if (thePrefs.GetVerbose())
			AddDebugLogLine(false, _T("PeerCacheQuery reqfile does not match ed2k reqfile; %s"), DbgGetClientInfo());
		return false;
	}

	if (m_pPCUpSocket != NULL)
	{
        SetPeerCacheUpState(PCUS_NONE);
		m_pPCUpSocket->Safe_Delete();
		ASSERT( m_pPCUpSocket == NULL );
	}
	m_pPCUpSocket = new CPeerCacheUpSocket(this);
	m_pPCUpSocket->SetTimeOut(GetPeerCacheSocketUploadTimeout());
	m_pPCUpSocket->Create();

	SOCKADDR_IN sockAddr = {0};
	sockAddr.sin_family = AF_INET;
	sockAddr.sin_port = htons(uCachePort);
	sockAddr.sin_addr.S_un.S_addr = uCacheIP;
	//Try to always tell the socket to WaitForOnConnect before you call Connect.
	m_pPCUpSocket->WaitForOnConnect();
	m_pPCUpSocket->Connect((SOCKADDR*)&sockAddr, sizeof sockAddr);

	CStringA strPCRequest;
	strPCRequest.AppendFormat("GIVE %u\r\n", uPushId);

	if (thePrefs.GetDebugClientTCPLevel() > 0){
		DebugSend("PeerCache-GIVE", this, pUploadFile->GetFileHash());
		Debug(_T("  %hs\n"), strPCRequest);
	}
	
	CRawPacket* pHttpPacket = new CRawPacket(strPCRequest);
	theStats.AddUpDataOverheadFileRequest(pHttpPacket->size);
	m_pPCUpSocket->SendPacket(pHttpPacket);
	m_pPCUpSocket->SetHttpState(HttpStateRecvExpected);
	m_bPeerCacheUpHit = false;
	SetPeerCacheUpState(PCUS_WAIT_CACHE_REPLY);
	//theApp.uploadBandwidthThrottler->AddToStandardList(0, m_pPCUpSocket);

	CSafeMemFile dataSend(128);
	dataSend.WriteUInt8(PCPCK_VERSION);
	dataSend.WriteUInt8(PCOP_RES);
	dataSend.WriteUInt8(3);
	CTag tagPushId(PCTAG_PUSHID, uPushId);
	tagPushId.WriteNewEd2kTag(&dataSend);
	CTag tagPublicIP(PCTAG_PUBLICIP, theApp.GetPublicIP());
	tagPublicIP.WriteNewEd2kTag(&dataSend);
	CTag tagFileId(PCTAG_FILEID, (BYTE*)aucFileHash);
	tagFileId.WriteNewEd2kTag(&dataSend);
	
	if (thePrefs.GetDebugClientTCPLevel() > 0){
		DebugSend("OP__PeerCacheAnswer", this, aucFileHash);
		Debug(_T("  PushId=%u  PublicIP=%s  FileId=%s\n"), tagPushId.GetInt(), ipstr(tagPublicIP.GetInt()), md4str(tagFileId.GetHash()));
	}
	
	Packet* pEd2kPacket = new Packet(&dataSend, OP_EMULEPROT, OP_PEERCACHE_ANSWER);
	theStats.AddUpDataOverheadFileRequest(pEd2kPacket->size);
	socket->SendPacket(pEd2kPacket);
	return true;
}