bool CThreadScheduler::DoAddTask(CThreadTask* task, bool overwrite) { // GetTick is too lowres, so we just use a counter to ensure that // the sorted order will match the order in which the tasks were added. static unsigned taskAge = 0; // Get the map for this task type, implicitly creating it as needed. CDescMap& map = m_taskDescs[task->GetType()]; CDescMap::value_type entry(task->GetDesc(), task); if (map.insert(entry).second) { AddDebugLogLineN(logThreads, wxT("Task scheduled: ") + task->GetType() + wxT(" - ") + task->GetDesc()); m_tasks.push_back(CEntryPair(task, taskAge++)); m_tasksDirty = true; } else if (overwrite) { AddDebugLogLineN(logThreads, wxT("Task overwritten: ") + task->GetType() + wxT(" - ") + task->GetDesc()); CThreadTask* existingTask = map[task->GetDesc()]; if (m_currentTask == existingTask) { // The duplicate is already being executed, abort it. m_currentTask->m_abort = true; } else { // Task not yet started, simply remove and delete. wxCHECK2(map.erase(existingTask->GetDesc()), /* Do nothing. */); delete existingTask; } m_tasks.push_back(CEntryPair(task, taskAge++)); map[task->GetDesc()] = task; m_tasksDirty = true; } else {
bool CAICHHashSet::CreatePartRecoveryData(uint64 nPartStartPos, CFileDataIO* fileDataOut, bool bDbgDontLoad) { wxASSERT( m_pOwner ); if (m_pOwner->IsPartFile() || m_eStatus != AICH_HASHSETCOMPLETE) { wxFAIL; return false; } if (m_pHashTree.m_nDataSize <= EMBLOCKSIZE) { wxFAIL; return false; } if (!bDbgDontLoad) { if (!LoadHashSet()) { AddDebugLogLineN(logSHAHashSet, CFormat(wxT("Created RecoveryData error: failed to load hashset. File: %s")) % m_pOwner->GetFileName()); SetStatus(AICH_ERROR); return false; } } bool bResult; uint8 nLevel = 0; uint32 nPartSize = min<uint64>(PARTSIZE, m_pOwner->GetFileSize()-nPartStartPos); m_pHashTree.FindHash(nPartStartPos, nPartSize,&nLevel); uint16 nHashsToWrite = (nLevel-1) + nPartSize/EMBLOCKSIZE + ((nPartSize % EMBLOCKSIZE != 0 )? 1:0); const bool bUse32BitIdentifier = m_pOwner->IsLargeFile(); if (bUse32BitIdentifier) { fileDataOut->WriteUInt16(0); // no 16bit hashs to write } fileDataOut->WriteUInt16(nHashsToWrite); uint64 nCheckFilePos = fileDataOut->GetPosition(); if (m_pHashTree.CreatePartRecoveryData(nPartStartPos, nPartSize, fileDataOut, 0, bUse32BitIdentifier)) { if (nHashsToWrite*(HASHSIZE+(bUse32BitIdentifier? 4u:2u)) != fileDataOut->GetPosition() - nCheckFilePos) { wxFAIL; AddDebugLogLineN( logSHAHashSet, CFormat(wxT("Created RecoveryData has wrong length. File: %s")) % m_pOwner->GetFileName() ); bResult = false; SetStatus(AICH_ERROR); } else { bResult = true; } } else { AddDebugLogLineN(logSHAHashSet, CFormat(wxT("Failed to create RecoveryData for '%s'")) % m_pOwner->GetFileName()); bResult = false; SetStatus(AICH_ERROR); } if (!bUse32BitIdentifier) { fileDataOut->WriteUInt16(0); // no 32bit hashs to write } if (!bDbgDontLoad) { FreeHashSet(); } return bResult; }
bool CKnownFileList::Append(CKnownFile *Record, bool afterHashing) { if (Record->GetFileSize() > 0) { const CMD4Hash& tkey = Record->GetFileHash(); CKnownFileMap::iterator it = m_knownFileMap.find(tkey); if (it == m_knownFileMap.end()) { m_knownFileMap[tkey] = Record; return true; } else { CKnownFile *existing = it->second; if (KnownFileMatches(Record, existing->GetFileName(), existing->GetLastChangeDatetime(), existing->GetFileSize())) { // The file is already on the list, ignore it. AddDebugLogLineN(logKnownFiles, CFormat(wxT("%s is already on the list")) % Record->GetFileName().GetPrintable()); return false; } else if (IsOnDuplicates(Record->GetFileName(), Record->GetLastChangeDatetime(), Record->GetFileSize())) { // The file is on the duplicates list, ignore it. // Should not happen, at least not after hashing. Or why did it get hashed in the first place then? AddDebugLogLineN(logKnownFiles, CFormat(wxT("%s is on the duplicates list")) % Record->GetFileName().GetPrintable()); return false; } else { if (afterHashing && existing->GetFileSize() == Record->GetFileSize()) { // We just hashed a "new" shared file and find it's already known under a different name or date. // Guess what - it was probably renamed or touched. // So copy over all properties from the existing known file and just keep name/date. time_t newDate = Record->GetLastChangeDatetime(); CPath newName = Record->GetFileName(); CMemFile f; existing->WriteToFile(&f); f.Reset(); Record->LoadFromFile(&f); Record->SetLastChangeDatetime(newDate); Record->SetFileName(newName); } // The file is a duplicated hash. Add THE OLD ONE to the duplicates list. // (This is used when reading the known file list where the duplicates are stored in front.) m_duplicateFileList.push_back(existing); if (theApp->sharedfiles) { // Removing the old kad keywords created with the old filename theApp->sharedfiles->RemoveKeywords(existing); } m_knownFileMap[tkey] = Record; return true; } } } else { AddDebugLogLineN(logGeneral, CFormat(wxT("%s is 0-size, not added")) % Record->GetFileName()); return false; } }
// Check all clients that uploaded corrupted data, // and ban them if they didn't upload enough good data too. void CCorruptionBlackBox::EvaluateData() { CCBBClientMap::iterator it = m_badClients.begin(); for (; it != m_badClients.end(); ++it) { uint32 ip = it->first; uint64 bad = it->second.m_downloaded; if (!bad) { wxFAIL; // this should not happen continue; } uint64 good = 0; CCBBClientMap::iterator it2 = m_goodClients.find(ip); if (it2 != m_goodClients.end()) { good = it2->second.m_downloaded; } int nCorruptPercentage = bad * 100 / (bad + good); if (nCorruptPercentage > CBB_BANTHRESHOLD) { CUpDownClient* pEvilClient = theApp->clientlist->FindClientByIP(ip); wxString clientName; if (pEvilClient != NULL) { clientName = pEvilClient->GetClientShortInfo(); AddDebugLogLineN(logPartFile, CFormat(wxT("CorruptionBlackBox(%s): Banning: Found client which sent %d of %d corrupted data, %s")) % m_partNumber % bad % (good + bad) % pEvilClient->GetClientFullInfo()); theApp->clientlist->AddTrackClient(pEvilClient); pEvilClient->Ban(); // Identified as sender of corrupt data // Stop download right away pEvilClient->SetDownloadState(DS_BANNED); if (pEvilClient->Disconnected(wxT("Upload of corrupted data"))) { pEvilClient->Safe_Delete(); } } else { clientName = Uint32toStringIP(ip); theApp->clientlist->AddBannedClient(ip); } AddLogLineN(CFormat(_("Banned client %s for sending %s corrupt data of %s total for the file '%s'")) % clientName % CastItoXBytes(bad) % CastItoXBytes(good + bad) % m_fileName); } else { CUpDownClient* pSuspectClient = theApp->clientlist->FindClientByIP(ip); if (pSuspectClient != NULL) { AddDebugLogLineN(logPartFile, CFormat(wxT("CorruptionBlackBox(%s): Reporting: Found client which probably sent %d of %d corrupted data, but it is within the acceptable limit, %s")) % m_partNumber % bad % (good + bad) % pSuspectClient->GetClientFullInfo()); theApp->clientlist->AddTrackClient(pSuspectClient); } else { AddDebugLogLineN(logPartFile, CFormat(wxT("CorruptionBlackBox(%s): Reporting: Found client which probably sent %d of %d corrupted data, but it is within the acceptable limit, %s")) % m_partNumber % bad % (good + bad) % Uint32toStringIP(ip)); } } } }
void CMuleUDPSocket::OnReceive(int errorCode) { AddDebugLogLineN(logMuleUDP, CFormat(wxT("Got UDP callback for read: Error %i Socket state %i")) % errorCode % Ok()); char buffer[UDP_BUFFER_SIZE]; amuleIPV4Address addr; unsigned length = 0; bool error = false; int lastError = 0; { wxMutexLocker lock(m_mutex); if (errorCode || (m_socket == NULL) || !m_socket->IsOk()) { DestroySocket(); CreateSocket(); return; } length = m_socket->RecvFrom(addr, buffer, UDP_BUFFER_SIZE); lastError = m_socket->LastError(); error = lastError != 0; } const uint32 ip = StringIPtoUint32(addr.IPAddress()); const uint16 port = addr.Service(); if (error) { OnReceiveError(lastError, ip, port); } else if (length < 2) { // 2 bytes (protocol and opcode) is the smallets possible packet. AddDebugLogLineN(logMuleUDP, m_name + wxT(": Invalid Packet received")); } else if (!ip) { // wxFAIL; AddLogLineNS(wxT("Unknown ip receiving a UDP packet! Ignoring: '") + addr.IPAddress() + wxT("'")); } else if (!port) { // wxFAIL; AddLogLineNS(wxT("Unknown port receiving a UDP packet! Ignoring")); } else if (theApp->clientlist->IsBannedClient(ip)) { AddDebugLogLineN(logMuleUDP, m_name + wxT(": Dropped packet from banned IP ") + addr.IPAddress()); } else { AddDebugLogLineN(logMuleUDP, (m_name + wxT(": Packet received (")) << addr.IPAddress() << wxT(":") << port << wxT("): ") << length << wxT("b")); OnPacketReceived(ip, port, (byte*)buffer, length); } }
bool CKnownFileList::Init() { CFile file; CPath fullpath = CPath(theApp->ConfigDir + m_filename); if (!fullpath.FileExists()) { // This is perfectly normal. The file was probably either // deleted, or this is the first time running aMule. return false; } if (!file.Open(fullpath)) { AddLogLineC(CFormat(_("WARNING: %s cannot be opened.")) % m_filename); return false; } try { uint8 version = file.ReadUInt8(); if ((version != MET_HEADER) && (version != MET_HEADER_WITH_LARGEFILES)) { AddLogLineC(_("WARNING: Known file list corrupted, contains invalid header.")); return false; } wxMutexLocker sLock(list_mut); uint32 RecordsNumber = file.ReadUInt32(); AddDebugLogLineN(logKnownFiles, CFormat(wxT("Reading %i known files from file format 0x%2.2x.")) % RecordsNumber % version); for (uint32 i = 0; i < RecordsNumber; i++) { CScopedPtr<CKnownFile> record; if (record->LoadFromFile(&file)) { AddDebugLogLineN(logKnownFiles, CFormat(wxT("Known file read: %s")) % record->GetFileName()); Append(record.release()); } else { AddLogLineC(_("Failed to load entry in known file list, file may be corrupt")); } } AddDebugLogLineN(logKnownFiles, wxT("Finished reading known files")); return true; } catch (const CInvalidPacket& e) { AddLogLineC(_("Invalid entry in known file list, file may be corrupt: ") + e.what()); } catch (const CSafeIOException& e) { AddLogLineC(CFormat(_("IO error while reading %s file: %s")) % m_filename % e.what()); } return false; }
bool CThreadScheduler::AddTask(CThreadTask* task, bool overwrite) { wxMutexLocker lock(s_lock); // When terminated (on shutdown), all tasks are ignored. if (s_terminated) { AddDebugLogLineN(logThreads, wxT("Task discarded: ") + task->GetDesc()); delete task; return false; } else if (s_scheduler == NULL) { s_scheduler = new CThreadScheduler(); AddDebugLogLineN(logThreads, wxT("Scheduler created.")); } return s_scheduler->DoAddTask(task, overwrite); }
bool CClientList::IncomingBuddy(Kademlia::CContact* contact, Kademlia::CUInt128* buddyID) { uint32_t nContactIP = wxUINT32_SWAP_ALWAYS(contact->GetIPAddress()); //If aMule already knows this client, abort this.. It could cause conflicts. //Although the odds of this happening is very small, it could still happen. if (FindClientByIP(nContactIP, contact->GetTCPPort())) { return false; } else if (IsKadFirewallCheckIP(nContactIP)) { // doing a kad firewall check with this IP, abort AddDebugLogLineN(logKadMain, wxT("Kad TCP firewallcheck / Buddy request collision for IP ") + Uint32toStringIP(nContactIP)); return false; } if (theApp->GetPublicIP() == nContactIP && thePrefs::GetPort() == contact->GetTCPPort()) { return false; // don't connect ourself } //Add client to the lists to be processed. CUpDownClient* pNewClient = new CUpDownClient(contact->GetTCPPort(), contact->GetIPAddress(), 0, 0, NULL, false, true ); pNewClient->SetKadPort(contact->GetUDPPort()); pNewClient->SetKadState(KS_INCOMING_BUDDY); byte ID[16]; contact->GetClientID().ToByteArray(ID); pNewClient->SetUserHash(CMD4Hash(ID)); buddyID->ToByteArray(ID); pNewClient->SetBuddyID(ID); AddToKadList(pNewClient); AddClient(pNewClient); return true; }
void CClientList::RequestBuddy(Kademlia::CContact* contact, uint8_t connectOptions) { uint32_t nContactIP = wxUINT32_SWAP_ALWAYS(contact->GetIPAddress()); // Don't connect to ourself if (theApp->GetPublicIP() == nContactIP && thePrefs::GetPort() == contact->GetTCPPort()) { return; } CUpDownClient* pNewClient = FindClientByIP(nContactIP, contact->GetTCPPort()); if (!pNewClient) { pNewClient = new CUpDownClient(contact->GetTCPPort(), contact->GetIPAddress(), 0, 0, NULL, false, true ); } else if (pNewClient->GetKadState() != KS_NONE) { return; // already busy with this client in some way (probably fw stuff), don't mess with it } else if (IsKadFirewallCheckIP(nContactIP)) { // doing a kad firewall check with this IP, abort AddDebugLogLineN(logKadMain, wxT("Kad TCP firewallcheck / Buddy request collision for IP ") + Uint32toStringIP(nContactIP)); return; } //Add client to the lists to be processed. pNewClient->SetKadPort(contact->GetUDPPort()); pNewClient->SetKadState(KS_QUEUED_BUDDY); uint8_t ID[16]; contact->GetClientID().ToByteArray(ID); pNewClient->SetUserHash(CMD4Hash(ID)); pNewClient->SetConnectOptions(connectOptions, true, false); AddToKadList(pNewClient); //This method checks if this is a dup already. AddClient(pNewClient); }
// 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)); } }
int CamuleDaemonApp::OnExit() { #ifdef AMULED28 /* * Stop all socket threads before entering * shutdown sequence. */ delete listensocket; listensocket = 0; if (clientudp) { delete clientudp; clientudp = NULL; } #endif ShutDown(); #ifndef __WXMSW__ int ret = sigaction(SIGCHLD, &m_oldSignalChildAction, NULL); if (ret == -1) { AddDebugLogLineC(logStandard, CFormat(wxT("CamuleDaemonApp::OnRun(): second sigaction() failed: %m."))); } else { AddDebugLogLineN(logGeneral, wxT("CamuleDaemonApp::OnRun(): Uninstallation of SIGCHLD callback with sigaction() succeeded.")); } #endif // __WXMSW__ // lfroen: delete socket threads if (ECServerHandler) { ECServerHandler = 0; } delete core_timer; return CamuleApp::OnExit(); }
void CDownloadQueue::AddDownload(CPartFile* file, bool paused, uint8 category) { wxCHECK_RET(!IsFileExisting(file->GetFileHash()), wxT("Adding duplicate part-file")); if (file->GetStatus(true) == PS_ALLOCATING) { file->PauseFile(); } else if (paused && GetFileCount()) { file->StopFile(); } { wxMutexLocker lock(m_mutex); m_filelist.push_back( file ); DoSortByPriority(); } NotifyObservers( EventType( EventType::INSERTED, file ) ); if (category < theApp->glob_prefs->GetCatCount()) { file->SetCategory(category); } else { AddDebugLogLineN( logDownloadQueue, wxT("Tried to add download into invalid category.") ); } Notify_DownloadCtrlAddFile( file ); theApp->searchlist->UpdateSearchFileByHash(file->GetFileHash()); // Update file in the search dialog if it's still open AddLogLineC(CFormat(_("Downloading %s")) % file->GetFileName() ); }
void CHttpStateMachine::process_state(t_sm_state state, bool entry) { (this->*m_process_state[state])(entry); #ifdef __DEBUG__ int n = 0; switch (state) { case HTTP_STATE_START: case HTTP_STATE_END: case HTTP_STATE_RECEIVE_COMMAND_REPLY: default: n = 0; break; case HTTP_STATE_SEND_COMMAND_REQUEST: n = m_packetLenght; break; case HTTP_STATE_PROCESS_COMMAND_REPLY: n = m_lastRead; break; } if (entry) { DumpMem(m_buffer, n, m_state_name[state], m_ok); } else { AddDebugLogLineN(logProxy, wxString(wxT("wait state -- ")) << m_state_name[state]); } #endif // __DEBUG__ }
void CPartFileConvert::StartThread() { if (!s_convertPfThread) { s_convertPfThread = new CPartFileConvert(); switch ( s_convertPfThread->Create() ) { case wxTHREAD_NO_ERROR: AddDebugLogLineN( logPfConvert, wxT("A new thread has been created.") ); break; case wxTHREAD_RUNNING: AddDebugLogLineC( logPfConvert, wxT("Error, attempt to create an already running thread!") ); break; case wxTHREAD_NO_RESOURCE: AddDebugLogLineC( logPfConvert, wxT("Error, attempt to create a thread without resources!") ); break; default: AddDebugLogLineC( logPfConvert, wxT("Error, unknown error attempting to create a thread!") ); } // The thread shouldn't hog the CPU, as it will already be hogging the HD s_convertPfThread->SetPriority(WXTHREAD_MIN_PRIORITY); s_convertPfThread->Run(); } }
// recursive // calculates missing hash from the existing ones // overwrites existing hashs // fails if no hash is found for any branch bool CAICHHashTree::ReCalculateHash(CAICHHashAlgo* hashalg, bool bDontReplace) { if (m_pLeftTree && m_pRightTree) { if ( !m_pLeftTree->ReCalculateHash(hashalg, bDontReplace) || !m_pRightTree->ReCalculateHash(hashalg, bDontReplace) ) { return false; } if (bDontReplace && m_bHashValid) { return true; } if (m_pRightTree->m_bHashValid && m_pLeftTree->m_bHashValid) { hashalg->Reset(); hashalg->Add(m_pLeftTree->m_Hash.GetRawHash(), HASHSIZE); hashalg->Add(m_pRightTree->m_Hash.GetRawHash(), HASHSIZE); hashalg->Finish(m_Hash); m_bHashValid = true; return true; } else { return m_bHashValid; } } else if (m_pLeftTree == NULL && m_pRightTree == NULL) { return true; } else { AddDebugLogLineN(logSHAHashSet, wxT("ReCalculateHash failed - Hashtree incomplete")); return false; } }
void OnSignalChildHandler(int /*signal*/, siginfo_t *siginfo, void * /*ucontext*/) { // Build the log message wxString msg; msg << wxT("OnSignalChildHandler() has been called for child process with pid `") << siginfo->si_pid << wxT("'. "); // Make sure we leave no zombies by calling waitpid() int status = 0; pid_t result = AmuleWaitPid(siginfo->si_pid, &status, WNOHANG, &msg); if (result != 1 && result != 0 && (WIFEXITED(status) || WIFSIGNALED(status))) { // Fetch the wxEndProcessData structure corresponding to this pid EndProcessDataMap::iterator it = endProcDataMap.find(siginfo->si_pid); if (it != endProcDataMap.end()) { wxEndProcessData *endProcData = it->second; // Remove this entry from the process map endProcDataMap.erase(siginfo->si_pid); // Save the exit code for the wxProcess object to read later endProcData->exitcode = result != -1 && WIFEXITED(status) ? WEXITSTATUS(status) : -1; // Make things work as in wxGUI wxHandleProcessTermination(endProcData); // wxHandleProcessTermination() will "delete endProcData;" // So we do not delete it again, ok? Do not uncomment this line. //delete endProcData; } else { msg << wxT(" Error: the child process pid is not on the pid map."); } } // Log our passage here AddDebugLogLineN(logGeneral, msg); }
bool CClientList::SendChatMessage(uint64 client_id, const wxString& message) { CUpDownClient* client = FindClientByIP(IP_FROM_GUI_ID(client_id), PORT_FROM_GUI_ID(client_id)); AddDebugLogLineN( logClient, wxT("Trying to Send Message.") ); if (client) { AddDebugLogLineN( logClient, wxT("Sending.") ); } else { AddDebugLogLineC( logClient, CFormat( wxT("No client (GUI_ID %lli [%s:%llu]) found in CClientList::SendChatMessage(). Creating") ) % client_id % Uint32toStringIP(IP_FROM_GUI_ID(client_id)) % PORT_FROM_GUI_ID(client_id) ); client = new CUpDownClient(PORT_FROM_GUI_ID(client_id),IP_FROM_GUI_ID(client_id),0,0,NULL, true, true); AddClient(client); } return client->SendChatMessage(message); }
int CDaemonAppTraits::WaitForChild(wxExecuteData &execData) { int status = 0; pid_t result = 0; // Build the log message wxString msg; msg << wxT("WaitForChild() has been called for child process with pid `") << execData.pid << wxT("'. "); if (execData.flags & wxEXEC_SYNC) { result = AmuleWaitPid(execData.pid, &status, 0, &msg); if (result == -1 || (!WIFEXITED(status) && !WIFSIGNALED(status))) { msg << wxT(" Waiting for subprocess termination failed."); AddDebugLogLineN(logGeneral, msg); } } else { /** wxEXEC_ASYNC */ // Give the process a chance to start or forked child to exit // 1 second is enough time to fail on "path not found" wxSleep(1); result = AmuleWaitPid(execData.pid, &status, WNOHANG, &msg); if (result == 0) { // Add a WxEndProcessData entry to the map, so that we can // support process termination wxEndProcessData *endProcData = new wxEndProcessData(); endProcData->pid = execData.pid; endProcData->process = execData.process; endProcData->tag = 0; endProcDataMap[execData.pid] = endProcData; status = execData.pid; } else { // if result != 0, then either waitpid() failed (result == -1) // and there is nothing we can do, or the child has changed // status, which means it is probably dead. status = 0; } } // Log our passage here AddDebugLogLineN(logGeneral, msg); return status; }
void CKnownFileList::Save() { CFile file(theApp->ConfigDir + m_filename, CFile::write_safe); if (!file.IsOpened()) { return; } wxMutexLocker sLock(list_mut); AddDebugLogLineN(logKnownFiles, CFormat(wxT("start saving %s")) % m_filename); try { // Kry - This is the version, but we don't know it till // we know if any largefile is saved. This allows the list // to be compatible with previous versions. bool bContainsAnyLargeFiles = false; file.WriteUInt8(0); file.WriteUInt32(m_knownFileMap.size() + m_duplicateFileList.size()); // Duplicates handling. Duplicates needs to be saved first, // since it is the last entry that gets used. KnownFileList::iterator itDup = m_duplicateFileList.begin(); for ( ; itDup != m_duplicateFileList.end(); ++itDup ) { (*itDup)->WriteToFile(&file); if ((*itDup)->IsLargeFile()) { bContainsAnyLargeFiles = true; } } CKnownFileMap::iterator it = m_knownFileMap.begin(); for (; it != m_knownFileMap.end(); ++it) { it->second->WriteToFile(&file); if (it->second->IsLargeFile()) { bContainsAnyLargeFiles = true; } } file.Seek(0); file.WriteUInt8(bContainsAnyLargeFiles ? MET_HEADER_WITH_LARGEFILES : MET_HEADER); file.Close(); } catch (const CIOFailureException& e) { AddLogLineC(CFormat(_("Error while saving %s file: %s")) % m_filename % e.what()); } AddDebugLogLineN(logKnownFiles, CFormat(wxT("finished saving %s")) % m_filename); }
void CThreadScheduler::Terminate() { AddDebugLogLineN(logThreads, wxT("Terminating scheduler")); CThreadScheduler* ptr = NULL; { wxMutexLocker lock(s_lock); // Safely unlink the scheduler, as to avoid race-conditions. ptr = s_scheduler; s_running = false; s_terminated = true; s_scheduler = NULL; } delete ptr; AddDebugLogLineN(logThreads, wxT("Scheduler terminated")); }
void CMuleUDPSocket::SendPacket(CPacket* packet, uint32 IP, uint16 port, bool bEncrypt, const uint8* pachTargetClientHashORKadID, bool bKad, uint32 nReceiverVerifyKey) { wxCHECK_RET(packet, wxT("Invalid packet.")); /*wxCHECK_RET(port, wxT("Invalid port.")); wxCHECK_RET(IP, wxT("Invalid IP.")); */ if (!port || !IP) { return; } if (!Ok()) { AddDebugLogLineN(logMuleUDP, (m_name + wxT(": Packet discarded, socket not Ok (")) << Uint32_16toStringIP_Port(IP, port) << wxT("): ") << packet->GetPacketSize() << wxT("b")); delete packet; return; } AddDebugLogLineN(logMuleUDP, (m_name + wxT(": Packet queued (")) << Uint32_16toStringIP_Port(IP, port) << wxT("): ") << packet->GetPacketSize() << wxT("b")); UDPPack newpending; newpending.IP = IP; newpending.port = port; newpending.packet = packet; newpending.time = GetTickCount(); newpending.bEncrypt = bEncrypt && (pachTargetClientHashORKadID != NULL || (bKad && nReceiverVerifyKey != 0)) && thePrefs::IsClientCryptLayerSupported(); newpending.bKad = bKad; newpending.nReceiverVerifyKey = nReceiverVerifyKey; if (newpending.bEncrypt && pachTargetClientHashORKadID != NULL) { md4cpy(newpending.pachTargetClientHashORKadID, pachTargetClientHashORKadID); } else { md4clr(newpending.pachTargetClientHashORKadID); } { wxMutexLocker lock(m_mutex); m_queue.push_back(newpending); } theApp->uploadBandwidthThrottler->QueueForSendingControlPacket(this); }
void CDownloadQueue::CheckAndAddKnownSource(CPartFile* sender,CUpDownClient* source) { // Kad reviewed if (sender->IsStopped()) { return; } // Filter sources which are known to be dead/useless if ( sender->IsDeadSource(source) ) { return; } // "Filter LAN IPs" -- this may be needed here in case we are connected to the internet and are also connected // to a LAN and some client from within the LAN connected to us. Though this situation may be supported in future // by adding that client to the source list and filtering that client's LAN IP when sending sources to // a client within the internet. // // "IPfilter" is not needed here, because that "known" client was already IPfiltered when receiving OP_HELLO. if (!source->HasLowID()) { uint32 nClientIP = wxUINT32_SWAP_ALWAYS(source->GetUserIDHybrid()); if (!IsGoodIP(nClientIP, thePrefs::FilterLanIPs())) { // check for 0-IP, localhost and LAN addresses AddDebugLogLineN(logIPFilter, wxT("Ignored already known source with IP=%s") + Uint32toStringIP(nClientIP)); return; } } // Filter sources which are incompatible with our encryption setting (one requires it, and the other one doesn't supports it) if ( (source->RequiresCryptLayer() && (!thePrefs::IsClientCryptLayerSupported() || !source->HasValidHash())) || (thePrefs::IsClientCryptLayerRequired() && (!source->SupportsCryptLayer() || !source->HasValidHash()))) { source->Safe_Delete(); return; } CPartFile* file = source->GetRequestFile(); // Check if the file is already queued for something else if ( file ) { if ( file != sender ) { if ( source->AddRequestForAnotherFile( sender ) ) { Notify_SourceCtrlAddSource( sender, CCLIENTREF(source, wxT("CDownloadQueue::CheckAndAddKnownSource Notify_SourceCtrlAddSource 1")), A4AF_SOURCE ); } } } else { source->SetRequestFile( sender ); if ( source->GetFileRating() || !source->GetFileComment().IsEmpty() ) { sender->UpdateFileRatingCommentAvail(); } source->SetSourceFrom(SF_PASSIVE); sender->AddSource( source ); Notify_SourceCtrlAddSource( sender, CCLIENTREF(source, wxT("CDownloadQueue::CheckAndAddKnownSource Notify_SourceCtrlAddSource 2")), UNAVAILABLE_SOURCE); } }
bool CClientList::AttachToAlreadyKnown(CUpDownClient** client, CClientTCPSocket* sender) { CUpDownClient* tocheck = (*client); CUpDownClient* found_client = FindMatchingClient( tocheck ); if ( tocheck == found_client ) { // We found the same client instance (client may have sent more than one OP_HELLO). do not delete that client! return true; } if (found_client != NULL){ if (sender) { if (found_client->GetSocket()) { if (found_client->IsConnected() && (found_client->GetIP() != tocheck->GetIP() || found_client->GetUserPort() != tocheck->GetUserPort() ) ) { // if found_client is connected and has the IS_IDENTIFIED, it's safe to say that the other one is a bad guy if (found_client->IsIdentified()){ AddDebugLogLineN(logClient, wxT("Client: ") + tocheck->GetUserName() + wxT("(") + tocheck->GetFullIP() + wxT("), Banreason: Userhash invalid")); tocheck->Ban(); return false; } AddDebugLogLineN(logClient, wxT("WARNING! Found matching client, to a currently connected client: ") + tocheck->GetUserName() + wxT("(") + tocheck->GetFullIP() + wxT(") and ") + found_client->GetUserName() + wxT("(") + found_client->GetFullIP() + wxT(")")); return false; } found_client->GetSocket()->Safe_Delete(); } found_client->SetSocket( sender ); tocheck->SetSocket( NULL ); } *client = 0; tocheck->Safe_Delete(); *client = found_client; return true; } return false; }
t_sm_state CProxyStateMachine::HandleEvent(t_sm_event event) { // Default is stay in current state t_sm_state ret = GetState(); switch(event) { case wxSOCKET_CONNECTION: AddDebugLogLineN(logProxy, wxT("Connection event")); m_isConnected = true; break; case wxSOCKET_INPUT: AddDebugLogLineN(logProxy, wxT("Input event")); m_canReceive = true; break; case wxSOCKET_OUTPUT: AddDebugLogLineN(logProxy, wxT("Output event")); m_canSend = true; break; case wxSOCKET_LOST: AddDebugLogLineN(logProxy, wxT("Lost connection event")); m_isLost = true; m_ok = false; break; default: AddDebugLogLineN(logProxy, wxT("Unknown event")); break; } // Aborting conditions: // - wxSOCKET_LOST event // - More than 10 times on the same state if ( m_isLost || GetClocksInCurrentState() > 10) { ret = PROXY_STATE_END; } return ret; }
void CAICHHashTree::SetBlockHash(uint64 nSize, uint64 nStartPos, CAICHHashAlgo* pHashAlg) { wxASSERT ( nSize <= EMBLOCKSIZE ); CAICHHashTree* pToInsert = FindHash(nStartPos, nSize); if (pToInsert == NULL) { // sanity wxFAIL; AddDebugLogLineN(logSHAHashSet, wxT("Critical Error: Failed to Insert SHA-HashBlock, FindHash() failed!")); return; } //sanity if (pToInsert->m_nBaseSize != EMBLOCKSIZE || pToInsert->m_nDataSize != nSize) { wxFAIL; AddDebugLogLineN(logSHAHashSet, wxT("Critical Error: Logical error on values in SetBlockHashFromData")); return; } pHashAlg->Finish(pToInsert->m_Hash); pToInsert->m_bHashValid = true; }
void CMuleUDPSocket::DestroySocket() { if (m_socket) { AddDebugLogLineN(logMuleUDP, wxT("Shutting down ") + m_name); m_socket->SetNotify(0); m_socket->Notify(false); m_socket->Close(); m_socket->Destroy(); m_socket = NULL; } }
// write the hash, specified by wHashIdent, with Data from fileInput. bool CAICHHashTree::SetHash(CFileDataIO* fileInput, uint32 wHashIdent, sint8 nLevel, bool bAllowOverwrite) { if (nLevel == (-1)) { // first call, check how many level we need to go uint8 i = 0; for (; i != 32 && (wHashIdent & 0x80000000) == 0; ++i) { wHashIdent <<= 1; } if (i > 31) { AddDebugLogLineN(logSHAHashSet, wxT("CAICHHashTree::SetHash - found invalid HashIdent (0)")); return false; } else { nLevel = 31 - i; } } if (nLevel == 0) { // this is the searched hash if (m_bHashValid && !bAllowOverwrite) { // not allowed to overwrite this hash, however move the filepointer by reading a hash CAICHHash(file); return true; } m_Hash.Read(fileInput); m_bHashValid = true; return true; } else if (m_nDataSize <= m_nBaseSize) { // sanity // this is already the last level, cant go deeper wxFAIL; return false; } else { // adjust ident to point the path to the next node wHashIdent <<= 1; nLevel--; uint64 nBlocks = m_nDataSize / m_nBaseSize + ((m_nDataSize % m_nBaseSize != 0 )? 1:0); uint64 nLeft = ( ((m_bIsLeftBranch) ? nBlocks+1:nBlocks) / 2)* m_nBaseSize; uint64 nRight = m_nDataSize - nLeft; if ((wHashIdent & 0x80000000) > 0) { if (m_pLeftTree == NULL) { m_pLeftTree = new CAICHHashTree(nLeft, true, (nLeft <= PARTSIZE) ? EMBLOCKSIZE : PARTSIZE); } else { wxASSERT( m_pLeftTree->m_nDataSize == nLeft ); } return m_pLeftTree->SetHash(fileInput, wHashIdent, nLevel); } else { if (m_pRightTree == NULL) { m_pRightTree = new CAICHHashTree(nRight, false, (nRight <= PARTSIZE) ? EMBLOCKSIZE : PARTSIZE); } else { wxASSERT( m_pRightTree->m_nDataSize == nRight ); } return m_pRightTree->SetHash(fileInput, wHashIdent, nLevel); } } }
void CFileAutoClose::Reopen() { if (m_autoClosed) { AddDebugLogLineN(logCFile, wxT("Reopen AutoClosed file ") + GetFilePath().GetPrintable()); m_file.Reopen(m_mode); // throws on failure // On open error m_autoClosed stays true, so if the app tries again // it opens and throws again. // Otherwise it would assert on an operation on a closed file and probably die. m_autoClosed = false; } m_lastAccess = TheTime; }
// Full debug output of all data void CCorruptionBlackBox::DumpAll() { #ifdef __DEBUG__ AddDebugLogLineN(logPartFile, wxT("CBB Dump Records")); std::map<uint16, CRecordList>::iterator it = m_Records.begin(); for (; it != m_Records.end(); ++it) { uint16 block = it->first; CRecordList & list = it->second; for (CRecordList::iterator it2 = list.begin(); it2 != list.end(); ++it2) { AddDebugLogLineN(logPartFile, CFormat(wxT("CBBD %6d %.16s %10d - %10d")) % block % Uint32toStringIP(it2->m_dwIP) % it2->m_nStartPos % it2->m_nEndPos); } } if (!m_goodClients.empty()) { AddDebugLogLineN(logPartFile, wxT("CBB Dump good Clients")); CCBBClientMap::iterator it3 = m_goodClients.begin(); for (; it3 != m_goodClients.end(); ++it3) { AddDebugLogLineN(logPartFile, CFormat(wxT("CBBD %.16s good %10d")) % Uint32toStringIP(it3->first) % it3->second.m_downloaded); } } if (!m_badClients.empty()) { AddDebugLogLineN(logPartFile, wxT("CBB Dump bad Clients")); CCBBClientMap::iterator it3 = m_badClients.begin(); for (; it3 != m_badClients.end(); ++it3) { AddDebugLogLineN(logPartFile, CFormat(wxT("CBBD %.16s bad %10d")) % Uint32toStringIP(it3->first) % it3->second.m_downloaded); } } #endif }
int CamuleDaemonApp::OnRun() { if (!thePrefs::AcceptExternalConnections()) { AddLogLineCS(_("ERROR: aMule daemon cannot be used when external connections are disabled. To enable External Connections, use either a normal aMule, start amuled with the option --ec-config or set the key \"AcceptExternalConnections\" to 1 in the file ~/.aMule/amule.conf")); return 0; } else if (thePrefs::ECPassword().IsEmpty()) { AddLogLineCS(_("ERROR: A valid password is required to use external connections, and aMule daemon cannot be used without external connections. To run aMule deamon, you must set the \"ECPassword\" field in the file ~/.aMule/amule.conf with an appropriate value. Execute amuled with the flag --ec-config to set the password. More information can be found at http://wiki.amule.org")); return 0; } #ifndef __WXMSW__ // Process the return code of dead children so that we do not create // zombies. wxBase does not implement wxProcess callbacks, so no one // actualy calls wxHandleProcessTermination() in console applications. // We do our best here. int ret = 0; ret = sigaction(SIGCHLD, NULL, &m_oldSignalChildAction); m_newSignalChildAction = m_oldSignalChildAction; m_newSignalChildAction.sa_sigaction = OnSignalChildHandler; m_newSignalChildAction.sa_flags |= SA_SIGINFO; m_newSignalChildAction.sa_flags &= ~SA_RESETHAND; ret = sigaction(SIGCHLD, &m_newSignalChildAction, NULL); if (ret == -1) { AddDebugLogLineC(logStandard, CFormat(wxT("CamuleDaemonApp::OnRun(): Installation of SIGCHLD callback with sigaction() failed: %m."))); } else { AddDebugLogLineN(logGeneral, wxT("CamuleDaemonApp::OnRun(): Installation of SIGCHLD callback with sigaction() succeeded.")); } #endif // __WXMSW__ #ifdef AMULED28 while ( !m_Exit ) { m_table->RunSelect(); ProcessPendingEvents(); ((CDaemonAppTraits *)GetTraits())->DeletePending(); } // ShutDown is beeing called twice. Once here and again in OnExit(). ShutDown(); return 0; #else #ifdef AMULED_DUMMY return 0; #else return wxApp::OnRun(); #endif #endif }