Esempio n. 1
0
void CDownloadQueue::Process()
{
	// send src requests to local server
	ProcessLocalRequests();
	
	{
		wxMutexLocker lock(m_mutex);

		uint32 downspeed = 0;
		if (thePrefs::GetMaxDownload() != UNLIMITED && m_datarate > 1500) {
			downspeed = (((uint32)thePrefs::GetMaxDownload())*1024*100)/(m_datarate+1); 
			if (downspeed < 50) {
				downspeed = 50;
			} else if (downspeed > 200) {
				downspeed = 200;
			}
		}
	
		m_datarate = 0;
		m_udcounter++;
		uint32 cur_datarate = 0;
		uint32 cur_udcounter = m_udcounter;
		
		std::list<int> m_sourcecountlist;

		bool mustPreventSleep = false;

		for ( uint16 i = 0; i < m_filelist.size(); i++ ) {
			CPartFile* file = m_filelist[i];
	
			CMutexUnlocker unlocker(m_mutex);
			
			uint8 status = file->GetStatus();
			mustPreventSleep |= !(status == PS_ERROR || status == PS_INSUFFICIENT || status == PS_PAUSED || status == PS_COMPLETE);

			if (status == PS_READY || status == PS_EMPTY ){
				cur_datarate += file->Process( downspeed, cur_udcounter );
			} else {
				//This will make sure we don't keep old sources to paused and stoped files..
				file->StopPausedFile();
			}

			if (!file->IsPaused() && !file->IsStopped()) {
				m_sourcecountlist.push_back(file->GetSourceCount());
			}
		}

		if (thePrefs::GetPreventSleepWhileDownloading()) {
			if ((mustPreventSleep == false) && (theStats::GetSessionSentBytes() < theStats::GetSessionReceivedBytes())) {
				// I can see right through your clever plan.
				mustPreventSleep = true;
			}

			if (mustPreventSleep) {
				PlatformSpecific::PreventSleepMode();
			} else {
				PlatformSpecific::AllowSleepMode();
			}
		} else {
			// Just in case the value changes while we're preventing. Calls to this function are totally inexpensive anwyay
			PlatformSpecific::AllowSleepMode();
		}


		// Set the source rarity thresholds
		int nSourceGroups = m_sourcecountlist.size();
		if (nSourceGroups) {
			m_sourcecountlist.sort();
			if (nSourceGroups == 1) {
				// High anyway.
				m_rareFileThreshold = m_sourcecountlist.front() + 1;
				m_commonFileThreshold = m_rareFileThreshold + 1;
			} else if (nSourceGroups == 2) {
				// One high, one low (unless they're both 0, then both high)
				m_rareFileThreshold = (m_sourcecountlist.back() > 0) ? (m_sourcecountlist.back() - 1) : 1;
				m_commonFileThreshold = m_rareFileThreshold + 1;
			} else {
				// More than two, time to do some math.

				// Lower 25% with the current #define values.
				int rarecutpoint = (nSourceGroups / RARITY_FACTOR); 
				for (int i = 0; i < rarecutpoint; ++ i) {
					m_sourcecountlist.pop_front();
				}
				m_rareFileThreshold = (m_sourcecountlist.front() > 0) ? (m_sourcecountlist.front() - 1) : 1;

				// 50% of the non-rare ones, with the curent #define values.
				int commoncutpoint = (nSourceGroups - rarecutpoint) / NORMALITY_FACTOR;
				for (int i = 0; i < commoncutpoint; ++ i) {
					m_sourcecountlist.pop_front();
				}
				m_commonFileThreshold = (m_sourcecountlist.front() > 0) ? (m_sourcecountlist.front() - 1) : 1;
			}
		} else {
			m_rareFileThreshold = RARE_FILE;
			m_commonFileThreshold = 100;
		}
	
		m_datarate += cur_datarate;

		if (m_udcounter == 5) {
			if (theApp->serverconnect->IsUDPSocketAvailable()) {
				if( (::GetTickCount() - m_lastudpstattime) > UDPSERVERSTATTIME) {
					m_lastudpstattime = ::GetTickCount();
					
					CMutexUnlocker unlocker(m_mutex);
					theApp->serverlist->ServerStats();
				}
			}
		}
	
		if (m_udcounter == 10) {
			m_udcounter = 0;
			if (theApp->serverconnect->IsUDPSocketAvailable()) {
				if ( (::GetTickCount() - m_lastudpsearchtime) > UDPSERVERREASKTIME) {
					SendNextUDPPacket();
				}
			}
		}
	
		if ( (::GetTickCount() - m_lastsorttime) > 10000 ) {
			DoSortByPriority();
		}
		// Check if any paused files can be resumed
			
		CheckDiskspace(thePrefs::GetTempDir());
	}
	
	
	// Check for new links once per second.
	if ((::GetTickCount() - m_nLastED2KLinkCheck) >= 1000) {
		theApp->AddLinksFromFile();
		m_nLastED2KLinkCheck = ::GetTickCount();
	}
}
Esempio n. 2
0
void CDownloadQueue::KademliaSearchFile(uint32_t searchID, const Kademlia::CUInt128* pcontactID, const Kademlia::CUInt128* pbuddyID, uint8_t type, uint32_t ip, uint16_t tcp, uint16_t udp, uint32_t buddyip, uint16_t buddyport, uint8_t byCryptOptions)
{
	AddDebugLogLineN(logKadSearch, CFormat(wxT("Search result sources (type %i)")) % type);

	//Safety measure to make sure we are looking for these sources
	CPartFile* temp = GetFileByKadFileSearchID(searchID);
	if( !temp ) {
		AddDebugLogLineN(logKadSearch, wxT("This is not the file we're looking for..."));
		return;
	}

	//Do we need more sources?
	if(!(!temp->IsStopped() && thePrefs::GetMaxSourcePerFile() > temp->GetSourceCount())) {
		AddDebugLogLineN(logKadSearch, wxT("No more sources needed for this file"));
		return;
	}

	uint32_t ED2KID = wxUINT32_SWAP_ALWAYS(ip);

	if (theApp->ipfilter->IsFiltered(ED2KID)) {
		AddDebugLogLineN(logKadSearch, wxT("Source ip got filtered"));
		AddDebugLogLineN(logIPFilter, CFormat(wxT("IPfiltered source IP=%s received from Kademlia")) % Uint32toStringIP(ED2KID));
		return;
	}

	if( (ip == Kademlia::CKademlia::GetIPAddress() || ED2KID == theApp->GetED2KID()) && tcp == thePrefs::GetPort()) {
		AddDebugLogLineN(logKadSearch, wxT("Trying to add myself as source, ignore"));
		return;
	}

	CUpDownClient* ctemp = NULL; 
	switch (type) {
		case 4:
		case 1: {
			// NonFirewalled users
			if(!tcp) {
				AddDebugLogLineN(logKadSearch, CFormat(wxT("Ignored source (IP=%s) received from Kademlia, no tcp port received")) % Uint32toStringIP(ip));
				return;
			}
			if (!IsGoodIP(ED2KID,thePrefs::FilterLanIPs())) {
				AddDebugLogLineN(logKadSearch, CFormat(wxT("%s got filtered")) % Uint32toStringIP(ED2KID));
				AddDebugLogLineN(logIPFilter, CFormat(wxT("Ignored source (IP=%s) received from Kademlia, filtered")) % Uint32toStringIP(ED2KID));
				return;
			}
			ctemp = new CUpDownClient(tcp, ip, 0, 0, temp, false, true);
			ctemp->SetSourceFrom(SF_KADEMLIA);
			// not actually sent or needed for HighID sources
			//ctemp->SetServerIP(serverip);
			//ctemp->SetServerPort(serverport);
			ctemp->SetKadPort(udp);
			byte cID[16];
			pcontactID->ToByteArray(cID);
			ctemp->SetUserHash(CMD4Hash(cID));
			break;
		}
		case 2: {
			// Don't use this type... Some clients will process it wrong..
			break;
		}
		case 5:
		case 3: {
			// This will be a firewalled client connected to Kad only.
			// We set the clientID to 1 as a Kad user only has 1 buddy.
			ctemp = new CUpDownClient(tcp, 1, 0, 0, temp, false, true);
			// The only reason we set the real IP is for when we get a callback
			// from this firewalled source, the compare method will match them.
			ctemp->SetSourceFrom(SF_KADEMLIA);
			ctemp->SetKadPort(udp);
			byte cID[16];
			pcontactID->ToByteArray(cID);
			ctemp->SetUserHash(CMD4Hash(cID));
			pbuddyID->ToByteArray(cID);
			ctemp->SetBuddyID(cID);
			ctemp->SetBuddyIP(buddyip);
			ctemp->SetBuddyPort(buddyport);
			break;
		}
		case 6: {
			// firewalled source which supports direct UDP callback
			// if we are firewalled ourself, the source is useless to us
			if (theApp->IsFirewalled()) {
				break;
			}

			if ((byCryptOptions & 0x08) == 0){
				AddDebugLogLineN(logKadSearch, CFormat(wxT("Received Kad source type 6 (direct callback) which has the direct callback flag not set (%s)")) % Uint32toStringIP(ED2KID));
				break;
			}

			ctemp = new CUpDownClient(tcp, 1, 0, 0, temp, false, true);
			ctemp->SetSourceFrom(SF_KADEMLIA);
			ctemp->SetKadPort(udp);
			ctemp->SetIP(ED2KID); // need to set the IP address, which cannot be used for TCP but for UDP
			byte cID[16];
			pcontactID->ToByteArray(cID);
			ctemp->SetUserHash(CMD4Hash(cID));
		}
	}

	if (ctemp) {
		// add encryption settings
		ctemp->SetConnectOptions(byCryptOptions);

		AddDebugLogLineN(logKadSearch, CFormat(wxT("Happily adding a source (%s) type %d")) % Uint32_16toStringIP_Port(ED2KID, ctemp->GetUserPort()) % type);
		CheckAndAddSource(temp, ctemp);
	}
}