bool operator==(const CDeadSource& ds1,const CDeadSource& ds2){
	ASSERT( ((ds1.m_dwID + ds1.m_dwServerIP) ^ isnulmd4(ds1.m_aucHash)) != 0 );
	ASSERT( ((ds2.m_dwID + ds2.m_dwServerIP) ^ isnulmd4(ds2.m_aucHash)) != 0 );
	return (
		// lowid ed2k and highid kad + ed2k check
		( (ds1.m_dwID != 0 && ds1.m_dwID == ds2.m_dwID) && ((ds1.m_nPort != 0 && ds1.m_nPort == ds2.m_nPort) || (ds1.m_nKadPort != 0 && ds1.m_nKadPort == ds2.m_nKadPort)) && (ds1.m_dwServerIP == ds2.m_dwServerIP || !IsLowID(ds1.m_dwID)) )
		// lowid kad check
		|| ( IsLowID(ds1.m_dwID) && isnulmd4(ds1.m_aucHash) == FALSE && md4cmp(ds1.m_aucHash, ds2.m_aucHash) == 0) );
}
示例#2
0
void CFileMgrDB::RemoveFile(CFileTaskItem * item, CONST BYTE * lpHash)
{
	CStringA strCmd, strCmd2;
	if(lpHash != NULL && !isnulmd4(lpHash))
	{
		CHAR strHash[33];
		md4strA(lpHash, strHash);
		strCmd.Format("SELECT id FROM files WHERE hash='%s'", strHash);
		strCmd2.Format("DELETE FROM files WHERE hash='%s'", strHash);
	}
	else
	{
		CStringA strUrl = StrToUtf8(item->m_strUrl);
		strUrl.Replace("'", "''");
		strCmd.Format("SELECT id FROM files WHERE url='%s'", strUrl);
		strCmd2.Format("DELETE FROM files WHERE url='%s'", strUrl);
	}

	if(!m_db->Prepare(strCmd))
		return;
	if(!m_db->Step())
	{
		m_db->Finalize();
		return;
	}
	UINT id = m_db->GetColInt(0);

	strCmd.Format("DELETE FROM urls WHERE fid=%d", id);
	SQL_EXEC(strCmd);
	SQL_EXEC(strCmd2);
}
示例#3
0
bool CFriend::TryToConnect(CFriendConnectionListener* pConnectionReport)
{
	if (m_FriendConnectState != FCS_NONE){
		m_liConnectionReport.AddTail(pConnectionReport);
		return true;
	}
	if (isnulmd4(m_abyKadID) && (m_dwLastUsedIP == 0 || m_nLastUsedPort == 0) 
		&& (GetLinkedClient() == NULL || GetLinkedClient()->GetIP() == 0 || GetLinkedClient()->GetUserPort() == 0))
	{
		pConnectionReport->ReportConnectionProgress(m_LinkedClient, _T("*** ") + GetResString(IDS_CONNECTING), false);
		pConnectionReport->ConnectingResult(GetLinkedClient(), false);	
		return false;
	}

	m_liConnectionReport.AddTail(pConnectionReport);
	if (GetLinkedClient(true) == NULL)
	{
		//ASSERT( pConnectionReport != &theApp.emuledlg->chatwnd->chatselector ); // shouldn't happen, if the chat connector calls, we he always should have a client for the session already
		ASSERT( false );
		GetClientForChatSession();
	}
	ASSERT( GetLinkedClient(true) != NULL );
	m_FriendConnectState = FCS_CONNECTING;
	m_LinkedClient->SetChatState(MS_CONNECTING);
	if (m_LinkedClient->socket != NULL && m_LinkedClient->socket->IsConnected())
	{
		// this client is already connected, but we need to check if it has also passed the secureident already
		UpdateFriendConnectionState(FCR_ESTABLISHED);
	}
	// otherwise (standard case) try to connect
	pConnectionReport->ReportConnectionProgress(m_LinkedClient, _T("*** ") + GetResString(IDS_CONNECTING), false);
	m_LinkedClient->TryToConnect(true);
	return true;
}
示例#4
0
void CFileMgrDB::UpdateUrl(CFileTaskItem * item, CUrlSite * lpSite, CONST BYTE * lpHash)
{
	CStringA strCmd, strUrl;
	if(lpHash != NULL && !isnulmd4(lpHash))
	{
		CHAR strHash[33];
		md4strA(lpHash, strHash);
		strCmd.Format("SELECT id FROM files WHERE hash='%s'", strHash);
	}
	else if(item->m_strUrl != "")
	{
		strUrl = StrToUtf8(item->m_strUrl);
		strUrl.Replace("'", "''");
		strCmd.Format("SELECT id FROM files WHERE url='%s'", StrToUtf8(item->m_strUrl));
	}
	else
		return;

	if(!m_db->Prepare(strCmd))
		return;
	if(!m_db->Step())
	{
		m_db->Finalize();
		return;
	}
	UINT id = m_db->GetColInt(0);

	strUrl = StrToUtf8(lpSite->m_strUrl);
	strUrl.Replace("'", "''");
	strCmd.Format("SELECT id FROM urls WHERE fid=%u AND url='%s'", id, strUrl);
	BOOL bReplace = FALSE;
	UINT uid = 0;
	if(m_db->Prepare(strCmd))
	{
		if(m_db->Step())
		{
			bReplace = TRUE;
			uid = m_db->GetColInt(0);
		}
		m_db->Finalize();
	}
	if(bReplace)
		strCmd.Format("UPDATE urls SET fid=%u, url='%s', fromwhere=%u, transnopay=%I64u, transpay=%I64u, badsite=%d, pref=%d, needci=%u WHERE id=%u", id, strUrl, lpSite->m_dwFromWhere, lpSite->m_dwDataTransferedWithoutPayload, lpSite->m_dwDataTransferedWithPayload, lpSite->m_bBadSite ? 1 : 0, lpSite->m_dwInitPreference, lpSite->m_bNeedCommitted ? 1 : 0, uid);
	else
		strCmd.Format("INSERT INTO urls (fid, url, fromwhere, transnopay, transpay, badsite, pref, needci) VALUES (%u,'%s',%u,%I64u,%I64u,%d,%d,%u)", id, strUrl, lpSite->m_dwFromWhere, lpSite->m_dwDataTransferedWithoutPayload, lpSite->m_dwDataTransferedWithPayload, lpSite->m_bBadSite ? 1 : 0, lpSite->m_dwInitPreference, lpSite->m_bNeedCommitted ? 1 : 0);
	SQL_EXEC(strCmd);
}
示例#5
0
bool CDeadSourceList::IsDeadSource(const CUpDownClient* pToCheck) const{
	uint32 dwExpTime;
	bool bDbgCheck = false;
	if(!pToCheck->HasLowID() || pToCheck->GetServerIP() != 0){
		if (m_mapDeadSources.Lookup(CDeadSource(pToCheck->GetUserIDHybrid(), pToCheck->GetUserPort(), pToCheck->GetServerIP(), pToCheck->GetKadPort()), dwExpTime)){
			if (dwExpTime > ::GetTickCount())
				return true;
		}
		bDbgCheck = true;
	}
	if ((pToCheck->HasValidBuddyID() && isnulmd4(pToCheck->GetUserHash()) == FALSE) || (pToCheck->HasLowID() && pToCheck->GetServerIP() == 0) ){
		if (m_mapDeadSources.Lookup(CDeadSource(pToCheck->GetUserHash()), dwExpTime)){
			if (dwExpTime > ::GetTickCount())
				return true;
		}
		bDbgCheck = true;
	}
	//ASSERT ( bDbgCheck );
	return false;
}
示例#6
0
bool CAbstractFile::HasNullHash() const
{
	return isnulmd4(m_abyFileHash);
}
// Encrypt packet. Key used:
// pachClientHashOrKadID != NULL									-> pachClientHashOrKadID
// pachClientHashOrKadID == NULL && bKad && nReceiverVerifyKey != 0 -> nReceiverVerifyKey
// else																-> ASSERT
int CEncryptedDatagramSocket::EncryptSendClient(uchar** ppbyBuf, int nBufLen, const uchar* pachClientHashOrKadID, bool bKad, uint32 nReceiverVerifyKey, uint32 nSenderVerifyKey) const{
	ASSERT( theApp.GetPublicIP() != 0 || bKad );
	ASSERT( thePrefs.IsClientCryptLayerSupported() );
	ASSERT( pachClientHashOrKadID != NULL || nReceiverVerifyKey != 0 );
	ASSERT( (nReceiverVerifyKey == 0 && nSenderVerifyKey == 0) || bKad );

	uint8 byPadLen = 0;			// padding disabled for UDP currently
	const uint32 nCryptHeaderLen = byPadLen + CRYPT_HEADER_WITHOUTPADDING + (bKad ? 8 : 0);
	
	uint32 nCryptedLen = nBufLen + nCryptHeaderLen;
	uchar* pachCryptedBuffer = new uchar[nCryptedLen];
	bool bKadRecKeyUsed = false;
	
	uint16 nRandomKeyPart = (uint16)cryptRandomGen.GenerateWord32(0x0000, 0xFFFF);
	MD5Sum md5;
	if (bKad){
		if ((pachClientHashOrKadID == NULL || isnulmd4(pachClientHashOrKadID)) && nReceiverVerifyKey != 0) {
			bKadRecKeyUsed = true;
			uchar achKeyData[6];
			PokeUInt32(achKeyData, nReceiverVerifyKey);
			PokeUInt16(achKeyData+4, nRandomKeyPart);
			md5.Calculate(achKeyData, sizeof(achKeyData));
			//DEBUG_ONLY( DebugLog(_T("Creating obfuscated Kad packet encrypted by ReceiverKey (%u)"), nReceiverVerifyKey) );  
		}
		else if (pachClientHashOrKadID != NULL && !isnulmd4(pachClientHashOrKadID)) {
			uchar achKeyData[18];
			md4cpy(achKeyData, pachClientHashOrKadID);
			PokeUInt16(achKeyData+16, nRandomKeyPart);
			md5.Calculate(achKeyData, sizeof(achKeyData));
			//DEBUG_ONLY( DebugLog(_T("Creating obfuscated Kad packet encrypted by Hash/NodeID %s"), md4str(pachClientHashOrKadID)) );  
		}
		else {
			ASSERT( false );
			delete[] pachCryptedBuffer;
			return nBufLen;
		}
	}
	else{
		uchar achKeyData[23];
		md4cpy(achKeyData, pachClientHashOrKadID);
		uint32 dwIP = theApp.GetPublicIP();
		memcpy(achKeyData+16, &dwIP, 4);
		memcpy(achKeyData+21, &nRandomKeyPart, 2);
		achKeyData[20] = MAGICVALUE_UDP;
		md5.Calculate(achKeyData, sizeof(achKeyData));
	}
	RC4_Key_Struct keySendKey;
	RC4CreateKey(md5.GetRawHash(), 16, &keySendKey, true);

	// create the semi random byte encryption header
	uint8 bySemiRandomNotProtocolMarker = 0;
	int i;
	for (i = 0; i < 128; i++){
		bySemiRandomNotProtocolMarker = cryptRandomGen.GenerateByte();
		bySemiRandomNotProtocolMarker = bKad ? (bySemiRandomNotProtocolMarker & 0xFE) : (bySemiRandomNotProtocolMarker | 0x01); // set the ed2k/kad marker bit
		if (bKad)
			bySemiRandomNotProtocolMarker = bKadRecKeyUsed ? ((bySemiRandomNotProtocolMarker & 0xFE) | 0x02) : (bySemiRandomNotProtocolMarker & 0xFC); // set the ed2k/kad and nodeid/reckey markerbit
		else
			bySemiRandomNotProtocolMarker = (bySemiRandomNotProtocolMarker | 0x01); // set the ed2k/kad marker bit
		
		bool bOk = false;
		switch (bySemiRandomNotProtocolMarker){ // not allowed values
			case OP_EMULEPROT:
			case OP_KADEMLIAPACKEDPROT:
			case OP_KADEMLIAHEADER:
			case OP_UDPRESERVEDPROT1:
			case OP_UDPRESERVEDPROT2:
			case OP_PACKEDPROT:
				break;
			default:
				bOk = true;
		}
		if (bOk)
			break;
	}
	if (i >= 128){
		// either we have _really_ bad luck or the randomgenerator is a bit messed up
		ASSERT( false );
		bySemiRandomNotProtocolMarker = 0x01;
	}

	uint32 dwMagicValue = MAGICVALUE_UDP_SYNC_CLIENT;
	pachCryptedBuffer[0] = bySemiRandomNotProtocolMarker;
	memcpy(pachCryptedBuffer + 1, &nRandomKeyPart, 2);
	RC4Crypt((uchar*)&dwMagicValue, pachCryptedBuffer + 3, 4, &keySendKey);
	RC4Crypt((uchar*)&byPadLen, pachCryptedBuffer + 7, 1, &keySendKey);

	for (int j = 0; j < byPadLen; j++){
		uint8 byRand = (uint8)rand();	// they actually dont really need to be random, but it doesn't hurts either
		RC4Crypt((uchar*)&byRand, pachCryptedBuffer + CRYPT_HEADER_WITHOUTPADDING + j, 1, &keySendKey);
	}

	if (bKad){
		RC4Crypt((uchar*)&nReceiverVerifyKey, pachCryptedBuffer + CRYPT_HEADER_WITHOUTPADDING + byPadLen, 4, &keySendKey);
		RC4Crypt((uchar*)&nSenderVerifyKey, pachCryptedBuffer + CRYPT_HEADER_WITHOUTPADDING + byPadLen + 4, 4, &keySendKey);
	}

	RC4Crypt(*ppbyBuf, pachCryptedBuffer + nCryptHeaderLen, nBufLen, &keySendKey);
	delete[] *ppbyBuf;
	*ppbyBuf = pachCryptedBuffer;

	//Xman
	// Maella -Accurate measure of bandwidth: eDonkey data + control, network adapter-
	/*
	theStats.AddUpDataOverheadCrypt(nCryptedLen - nBufLen);
	*/
	theApp.pBandWidthControl->AddeMuleOutObfuscationUDP(nCryptedLen - nBufLen);
	//Xman end

	return nCryptedLen;
}
示例#8
0
void CFileMgrDB::UpdateFile(CFileTaskItem * item, CONST BYTE * lpHash, BOOL bNew, BOOL bUpdateUrl)
{
	CStringA strCmd, strCmd2;
	CHAR strHash[33];
	UINT id = 0;
	if(lpHash != NULL && !isnulmd4(lpHash))
	{
		md4strA(lpHash, strHash);
		strCmd.Format("SELECT id FROM files WHERE hash='%s'", strHash);
		if(m_db->Prepare(strCmd))
		{
			if(m_db->Step())
			{
				bNew = FALSE; 
				id = m_db->GetColInt(0);
			}
			m_db->Finalize();
		}
	}
	else if(item->m_strUrl != "")
	{
		strHash[0] = 0;
		strCmd.Format("SELECT id FROM files WHERE url='%s'", StrToUtf8(item->m_strUrl));
		if(m_db->Prepare(strCmd))
		{
			if(m_db->Step())
			{
				bNew = FALSE;
				id = m_db->GetColInt(0);
			}
			m_db->Finalize();
		}
	}
	else
		return;
	CStringA strPath = StrToUtf8(item->m_strFilePath), strUrl = StrToUtf8(item->m_strUrl), strName = StrToUtf8(item->m_FileName), strLink = StrToUtf8(item->m_strEd2kLink);
	strPath.Replace("'", "''");
	strUrl.Replace("'", "''");
	strName.Replace("'", "''");
	strLink.Replace("'", "''");
	if(bNew)
		strCmd2.Format("INSERT INTO files (hash, state, path, url, size, name, ed2klink, filetime, metbakid) "
		"VALUES ('%s',%u,'%s','%s',%I64u,'%s','%s',%I64u,%u)", strHash, item->m_nFileState, strPath, strUrl, item->m_FileSize, strName,
		strLink, item->m_tFiletime.GetTime(), item->m_metBakId);
	else
		strCmd2.Format("UPDATE files SET hash='%s', state=%u, path='%s', url='%s', size=%I64u, name='%s', ed2klink='%s', "
		"filetime=%I64u, metbakid=%u WHERE id=%u", strHash, item->m_nFileState, strPath, strUrl, item->m_FileSize,strName, 
		strLink, item->m_tFiletime.GetTime(), item->m_metBakId, id);
	SQL_EXEC(strCmd2);
	if(bNew)
	{
		if(!m_db->Prepare(strCmd))
			return;
		if(!m_db->Step())
		{
			m_db->Finalize();
			return;
		}
		id = m_db->GetColInt(0);
	}

	if(!bUpdateUrl)
		return;

	strCmd.Format("DELETE FROM urls WHERE fid=%d", id);
	SQL_EXEC(strCmd);
	POSITION pos = item->m_lMetaLinkURLList.GetHeadPosition();
	while (pos)
	{
		CUrlSite pSite = item->m_lMetaLinkURLList.GetNext(pos);
		strUrl = StrToUtf8(pSite.m_strUrl);
		strUrl.Replace("'", "''");
		strCmd.Format("INSERT INTO urls (fid, url, fromwhere, transnopay, transpay, badsite, pref, needci) VALUES (%u,'%s',%u,%I64u,%I64u,%d,%d,%u)", id, strUrl, pSite.m_dwFromWhere, pSite.m_dwDataTransferedWithoutPayload, pSite.m_dwDataTransferedWithPayload, pSite.m_bBadSite ? 1 : 0, pSite.m_dwInitPreference, pSite.m_bNeedCommitted ? 1 : 0);
		SQL_EXEC(strCmd);
	}
}
示例#9
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;
}
示例#10
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;
}
示例#11
0
void CFriend::UpdateFriendConnectionState(EFriendConnectReport eEvent)
{
/*#ifdef _DEBUG
	CString strDbg;
	strDbg.Format(_T("*** Debug: UpdateFriendConnectionState, Report: %u, CurrentState: %u \n"), eEvent, m_FriendConnectState); 
	for (POSITION pos = m_liConnectionReport.GetHeadPosition(); pos != 0;)
		m_liConnectionReport.GetNext(pos)->ReportConnectionProgress(GetLinkedClient(), strDbg, false);			
#endif*/
	if (m_FriendConnectState == FCS_NONE || GetLinkedClient(true) == NULL){
		// we aren't currently trying to build up a friendconnection, we shouldn't be called
		ASSERT( false );
		return;
	}
	switch (eEvent){
		case FCR_ESTABLISHED:
		case FCR_USERHASHVERIFIED:
			// connection established, userhash fits, check secureident
			if (GetLinkedClient()->HasPassedSecureIdent(true)) {
				// well here we are done, connecting worked out fine
				m_FriendConnectState = FCS_NONE;
				for (POSITION pos = m_liConnectionReport.GetHeadPosition(); pos != 0;)
					m_liConnectionReport.GetNext(pos)->ConnectingResult(GetLinkedClient(), true);
				m_liConnectionReport.RemoveAll();
				FindKadID(); // fetch the kadid of this friend if we don't have it already
			}
			else
			{
				ASSERT( eEvent != FCR_USERHASHVERIFIED );
				// we connected, the userhash matches, now we wait for the authentification
				// nothing todo, just report about it
				for (POSITION pos = m_liConnectionReport.GetHeadPosition(); pos != 0; m_liConnectionReport.GetNext(pos)){
					m_liConnectionReport.GetAt(pos)->ReportConnectionProgress(GetLinkedClient(),  _T(" ...") + GetResString(IDS_TREEOPTIONS_OK) + _T("\n"), true);
					m_liConnectionReport.GetAt(pos)->ReportConnectionProgress(GetLinkedClient(), _T("*** ") + CString(_T("Authenticating friend")) /*to stringlist*/, false);
				}
				if (m_FriendConnectState == FCS_CONNECTING)
					m_FriendConnectState = FCS_AUTH;
				else{ // client must have connected to use while we tried something else (like search for him an kad)
					ASSERT( false );
					m_FriendConnectState = FCS_AUTH;
				}
			}
			break;
		case FCR_DISCONNECTED:
			// disconnected, lets see which state we were in
			if (m_FriendConnectState == FCS_CONNECTING || m_FriendConnectState == FCS_AUTH){
				if (m_FriendConnectState == FCS_CONNECTING && Kademlia::CKademlia::IsRunning()
					&&  Kademlia::CKademlia::IsConnected() && !isnulmd4(m_abyKadID)
					&& (m_dwLastKadSearch == 0 || ::GetTickCount() - m_dwLastKadSearch > MIN2MS(10)))
				{
					// connecting failed to the last known IP, now we search kad for an updated IP of our friend
					m_FriendConnectState = FCS_KADSEARCHING;
					m_dwLastKadSearch = ::GetTickCount();
					for (POSITION pos = m_liConnectionReport.GetHeadPosition(); pos != 0; m_liConnectionReport.GetNext(pos)){
						m_liConnectionReport.GetAt(pos)->ReportConnectionProgress(GetLinkedClient(), _T(" ...") + GetResString(IDS_FAILED) + _T("\n"), true);
						m_liConnectionReport.GetAt(pos)->ReportConnectionProgress(GetLinkedClient(), _T("*** ") + GetResString(IDS_SEARCHINGFRIENDKAD), false);
					}
					Kademlia::CKademlia::FindIPByNodeID(*this, m_abyKadID);
					break;
				}
				m_FriendConnectState = FCS_NONE;
				for (POSITION pos = m_liConnectionReport.GetHeadPosition(); pos != 0;)
					m_liConnectionReport.GetNext(pos)->ConnectingResult(GetLinkedClient(), false);
				m_liConnectionReport.RemoveAll();
			}
			else // FCS_KADSEARCHING, shouldn't happen
				ASSERT( false );
			break;
		case FCR_USERHASHFAILED:{
			// the client we connected to, had a different userhash then we expected
			// drop the linked client object and create a new one, because we don't want to have anything todo
			// with this instance as it is not our friend which we try to connect to
			// the connection try counts as failed
			CUpDownClient* pOld = m_LinkedClient;
			SetLinkedClient(NULL); // removing old one
			GetClientForChatSession(); // creating new instance with the hash we search for
			m_LinkedClient->SetChatState(MS_CONNECTING);
			for (POSITION pos = m_liConnectionReport.GetHeadPosition(); pos != 0;) // inform others about the change
				m_liConnectionReport.GetNext(pos)->ClientObjectChanged(pOld, GetLinkedClient());
			pOld->SetChatState(MS_NONE);

			if (m_FriendConnectState == FCS_CONNECTING || m_FriendConnectState == FCS_AUTH){
				ASSERT( m_FriendConnectState == FCS_AUTH );
				// todo: kad here
				m_FriendConnectState = FCS_NONE;
				for (POSITION pos = m_liConnectionReport.GetHeadPosition(); pos != 0;)
					m_liConnectionReport.GetNext(pos)->ConnectingResult(GetLinkedClient(), false);
				m_liConnectionReport.RemoveAll();
			}
			else // FCS_KADSEARCHING, shouldn't happen
				ASSERT( false );
			break;
		}
		case FCR_SECUREIDENTFAILED:
			// the client has the fitting userhash, but failed secureident - so we don't want to talk to him
			// we stop our search here in any case, multiple clientobjects with the same userhash would mess with other things
			// and its unlikely that we would find him on kad in this case too
			ASSERT( m_FriendConnectState == FCS_AUTH );
			m_FriendConnectState = FCS_NONE;
			for (POSITION pos = m_liConnectionReport.GetHeadPosition(); pos != 0;)
				m_liConnectionReport.GetNext(pos)->ConnectingResult(GetLinkedClient(), false);
			m_liConnectionReport.RemoveAll();
			break;
		case FCR_DELETED:
			// mh, this should actually never happen i'm sure
			// todo: in any case, stop any connection tries, notify other etc
			m_FriendConnectState = FCS_NONE;
			for (POSITION pos = m_liConnectionReport.GetHeadPosition(); pos != 0;)
				m_liConnectionReport.GetNext(pos)->ConnectingResult(GetLinkedClient(), false);
			m_liConnectionReport.RemoveAll();
			break;
		default:
			ASSERT( false );
	}
}
示例#12
0
bool CFriend::HasKadID() const
{
	return isnulmd4(m_abyKadID) == 0;
}
示例#13
0
bool CFriend::HasUserhash() const
{
	return isnulmd4(m_abyUserhash) == 0;
}