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) ); }
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); }
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; }
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); }
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; }
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; }
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); } }
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; }
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; }
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 ); } }
bool CFriend::HasKadID() const { return isnulmd4(m_abyKadID) == 0; }
bool CFriend::HasUserhash() const { return isnulmd4(m_abyUserhash) == 0; }