// Store a piece of received data (don't know if it's good or bad yet). // Data is stored in a list for the chunk in belongs to. void CCorruptionBlackBox::TransferredData(uint64 nStartPos, uint64 nEndPos, uint32 senderIP) { if (nStartPos > nEndPos) { wxFAIL; return; } // convert pos to relative block pos uint16 nPart = (uint16)(nStartPos / PARTSIZE); uint32 nRelStartPos = nStartPos - nPart*PARTSIZE; uint32 nRelEndPos = nEndPos - nPart*PARTSIZE; if (nRelEndPos >= PARTSIZE) { // data crosses the partborder, split it // (for the fun of it, this should never happen) nRelEndPos = PARTSIZE-1; TransferredData((nPart+1)*PARTSIZE, nEndPos, senderIP); } // // Let's keep things simple. // We don't request data we already have. // We check if received data exceeds block boundaries. // -> There should not be much overlap here. // So just stuff everything received into the list and only join adjacent blocks. // CRecordList & list = m_Records[nPart]; // this creates the entry if it doesn't exist yet bool merged = false; for (CRecordList::iterator it = list.begin(); it != list.end() && !merged; ++it) { merged = it->Merge(nRelStartPos, nRelEndPos, senderIP); } if (!merged) { list.push_back(CCBBRecord(nRelStartPos, nRelEndPos, senderIP)); AddDebugLogLineN(logPartFile, CFormat(wxT("CorruptionBlackBox(%s): transferred: new record for part %d (%d - %d, %s)")) % m_partNumber % nPart % nRelStartPos % nRelEndPos % Uint32toStringIP(senderIP)); } }
void CCorruptionBlackBox::TransferredData(uint32 nStartPos, uint32 nEndPos, const CUpDownClient* pSender){ if (nEndPos - nStartPos >= PARTSIZE){ ASSERT( false ); return; } if (nStartPos > nEndPos){ ASSERT( false ); return; } uint32 dwSenderIP = pSender->GetIP(); // we store records seperated for each part, so we don't have to search all entries everytime // convert pos to relative block pos uint16 nPart = nStartPos / PARTSIZE; uint32 nRelStartPos = nStartPos - nPart*PARTSIZE; uint32 nRelEndPos = nEndPos - nPart*PARTSIZE; if (nRelEndPos >= PARTSIZE){ // data crosses the partborder, split it nRelEndPos = PARTSIZE-1; uint32 nTmpStartPos = nPart*PARTSIZE + nRelEndPos + 1; ASSERT( nTmpStartPos % PARTSIZE == 0); // remove later TransferredData(nTmpStartPos, nEndPos, pSender); } if (nPart >= m_aaRecords.GetCount()){ //ASSERT( false ); m_aaRecords.SetSize(nPart+1); } int posMerge = -1; uint32 ndbgRewritten = 0; for (int i= 0; i < m_aaRecords[nPart].GetCount(); i++){ if (m_aaRecords[nPart][i].CanMerge(nRelStartPos, nRelEndPos, dwSenderIP, BBR_NONE)){ posMerge = i; } // check if there is already an pending entry and overwrite it else if (m_aaRecords[nPart][i].m_BBRStatus == BBR_NONE){ if (m_aaRecords[nPart][i].m_nStartPos >= nRelStartPos && m_aaRecords[nPart][i].m_nEndPos <= nRelEndPos){ // old one is included in new one -> delete ndbgRewritten += (m_aaRecords[nPart][i].m_nEndPos-m_aaRecords[nPart][i].m_nStartPos)+1; m_aaRecords[nPart].RemoveAt(i); i--; } else if (m_aaRecords[nPart][i].m_nStartPos < nRelStartPos && m_aaRecords[nPart][i].m_nEndPos > nRelEndPos){ // old one includes new one // check if the old one and new one have the same ip if (dwSenderIP != m_aaRecords[nPart][i].m_dwIP){ // different IP, means we have to split it 2 times uint32 nTmpEndPos1 = m_aaRecords[nPart][i].m_nEndPos; uint32 nTmpStartPos1 = nRelEndPos + 1; uint32 nTmpStartPos2 = m_aaRecords[nPart][i].m_nStartPos; uint32 nTmpEndPos2 = nRelStartPos - 1; m_aaRecords[nPart][i].m_nEndPos = nRelEndPos; m_aaRecords[nPart][i].m_nStartPos = nRelStartPos; uint32 dwOldIP = m_aaRecords[nPart][i].m_dwIP; m_aaRecords[nPart][i].m_dwIP = dwSenderIP; m_aaRecords[nPart].Add(CCBBRecord(nTmpStartPos1,nTmpEndPos1, dwOldIP)); m_aaRecords[nPart].Add(CCBBRecord(nTmpStartPos2,nTmpEndPos2, dwOldIP)); // and are done then } DEBUG_ONLY( AddDebugLogLine(DLP_DEFAULT, false, _T("CorruptionBlackBox: Debug: %i bytes were rewritten and records replaced with new stats (1)"), (nRelEndPos - nRelStartPos)+1) ); return; } else if (m_aaRecords[nPart][i].m_nStartPos >= nRelStartPos && m_aaRecords[nPart][i].m_nStartPos <= nRelEndPos){ // old one laps over new one on the right site ASSERT( nRelEndPos - m_aaRecords[nPart][i].m_nStartPos > 0 ); ndbgRewritten += nRelEndPos - m_aaRecords[nPart][i].m_nStartPos; m_aaRecords[nPart][i].m_nStartPos = nRelEndPos + 1; } else if (m_aaRecords[nPart][i].m_nEndPos >= nRelStartPos && m_aaRecords[nPart][i].m_nEndPos <= nRelEndPos){ // old one laps over new one on the left site ASSERT( m_aaRecords[nPart][i].m_nEndPos - nRelStartPos > 0 ); ndbgRewritten += m_aaRecords[nPart][i].m_nEndPos - nRelStartPos; m_aaRecords[nPart][i].m_nEndPos = nRelStartPos - 1; } } } if (posMerge != (-1) ){ VERIFY( m_aaRecords[nPart][posMerge].Merge(nRelStartPos, nRelEndPos, dwSenderIP, BBR_NONE) ); } else m_aaRecords[nPart].Add(CCBBRecord(nRelStartPos, nRelEndPos, dwSenderIP, BBR_NONE)); if (ndbgRewritten > 0){ DEBUG_ONLY( AddDebugLogLine(DLP_DEFAULT, false, _T("CorruptionBlackBox: Debug: %i bytes were rewritten and records replaced with new stats (2)"), ndbgRewritten) ); } }