⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 search.cpp

📁 wxWidgets写的电驴
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//// This file is part of the aMule Project.//// Copyright (c) 2004-2006 Angel Vidal (Kry) ( kry@amule.org )// Copyright (c) 2004-2006 aMule Team ( admin@amule.org / http://www.amule.org )// Copyright (c) 2003 Barry Dunne (http://www.emule-project.net)//// Any parts of this program derived from the xMule, lMule or eMule project,// or contributed by third-party developers are copyrighted by their// respective authors.//// This program is free software; you can redistribute it and/or modify// it under the terms of the GNU General Public License as published by// the Free Software Foundation; either version 2 of the License, or// (at your option) any later version.//// This program is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the// GNU General Public License for more details.// // You should have received a copy of the GNU General Public License// along with this program; if not, write to the Free Software// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA//// Note To Mods ///*Please do not change anything here and release it..There is going to be a new forum created just for the Kademlia side of the client..If you feel there is an error or a way to improve something, pleasepost it in the forum first and let us look at it.. If it is a real improvement,it will be added to the offical client.. Changing something without knowingwhat all it does can cause great harm to the network if released in mass form..Any mod that changes anything within the Kademlia side will not be allowed to advertisethere client on the eMule forum..*/#include "../../Tag.h"typedef CTag ed2kCTag;#include "Search.h"#include "Kademlia.h"#include "../../OPCodes.h"#include "Defines.h"#include "Prefs.h"#include "Indexed.h"#include "../io/IOException.h"#include "../routing/RoutingZone.h"#include "../routing/Contact.h"#include "../net/KademliaUDPListener.h"#include "../kademlia/Tag.h"#include "../../amule.h"#include "../../SharedFileList.h"#include "../../OtherFunctions.h"#include "../../KnownFile.h"#include "DownloadQueue.h"#include "PartFile.h"#include "SearchList.h"#include "MemFile.h"#include "ServerConnect.h"#include "Server.h"#include "ClientList.h"#include "updownclient.h"#include "Logger.h"#include "../../Preferences.h"#ifdef _DEBUG#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE[] = __FILE__;#endif////////////////////////////////////////using namespace Kademlia;////////////////////////////////////////CSearch::CSearch(){	m_created = time(NULL);	m_searchTerms = NULL;	m_type = (uint32)-1;	m_answers = 0;	m_totalRequestAnswers = 0;	m_kadPacketSent = 0;	m_searchID = (uint32)-1;	m_keywordPublish = 0;	(void)m_fileName;	m_stoping = false;	m_totalLoad = 0;	m_totalLoadResponses = 0;	bio1 = NULL;	bio2 = NULL;	bio3 = NULL;	m_lastResponse = time(NULL);}CSearch::~CSearch(){		CPartFile* temp = theApp.downloadqueue->GetFileByKadFileSearchID(getSearchID());		if(temp) {		temp->SetKadFileSearchID(0);	}			delete m_searchTerms;	ContactMap::iterator it;	for (it = m_inUse.begin(); it != m_inUse.end(); it++) {		((CContact*)it->second)->decUse();	}	ContactList::const_iterator it2;	for (it2 = m_delete.begin(); it2 != m_delete.end(); it2++) {		delete *it2;	}		delete bio1;	delete bio2;	delete bio3;	if(CKademlia::isRunning() && getNodeLoad() > 20) {		switch(getSearchTypes()) {			case CSearch::STOREKEYWORD:				Kademlia::CKademlia::getIndexed()->AddLoad(getTarget(), ((uint32)(DAY2S(7)*((double)getNodeLoad()/100.0))+(uint32)time(NULL)));				break;			default:				;				// WTF? 		}	}}void CSearch::go(void){	// Start with a lot of possible contacts, this is a fallback in case search stalls due to dead contacts	if (m_possible.empty()) {		CUInt128 distance(CKademlia::getPrefs()->getKadID());		distance.XOR(m_target);		CKademlia::getRoutingZone()->getClosestTo(3, m_target, distance, 50, &m_possible, true, true);	}		if (m_possible.empty()) {		return;	}	ContactMap::iterator it;	//Lets keep our contact list entries in mind to dec the inUse flag.	for (it = m_possible.begin(); it != m_possible.end(); ++it) {		m_inUse[it->first] = it->second;	}	wxASSERT(m_possible.size() == m_inUse.size());	// Take top 3 possible	int count = min(ALPHA_QUERY, (int)m_possible.size());	CContact *c;	for (int i=0; i<count; i++) {		it = m_possible.begin();		c = it->second;		// Move to tried		m_tried[it->first] = c;		m_possible.erase(it);		// Send request		c->checkingType();		sendFindValue(c->getClientID(), c->getIPAddress(), c->getUDPPort());		if(m_type == NODE) {			break;		}	}}//If we allow about a 15 sec delay before deleting, we won't miss a lot of delayed returning packets.void CSearch::prepareToStop(){	if( m_stoping ) {		return;	}	uint32 baseTime = 0;	switch(m_type) {		case NODE:		case NODECOMPLETE:			baseTime = SEARCHNODE_LIFETIME;			break;		case FILE:			baseTime = SEARCHFILE_LIFETIME;			break;		case KEYWORD:			baseTime = SEARCHKEYWORD_LIFETIME;			break;		case NOTES:			baseTime = SEARCHNOTES_LIFETIME;			break;		case STOREFILE:            baseTime = SEARCHSTOREFILE_LIFETIME;			break;		case STOREKEYWORD:			baseTime = SEARCHSTOREKEYWORD_LIFETIME;			break;		case STORENOTES:			baseTime = SEARCHSTORENOTES_LIFETIME;			break;		case FINDBUDDY:			baseTime = SEARCHFINDBUDDY_LIFETIME;			break;		case FINDSOURCE:			baseTime = SEARCHFINDSOURCE_LIFETIME;			break;		default:			baseTime = SEARCH_LIFETIME;	}	m_created = time(NULL) - baseTime + SEC(15);	m_stoping = true;	}void CSearch::jumpStart(void){	if (m_possible.empty()) {		prepareToStop();		return;	}	if ((time_t)(m_lastResponse + SEC(3)) > time(NULL)) {		return;	}	while (!m_possible.empty()) {				CContact *c = m_possible.begin()->second;			//Have we already tried to contact this node.		if (m_tried.count(m_possible.begin()->first) > 0) {			//Did we get a response from this node, if so, try to store or get info.			if(m_responded.count(m_possible.begin()->first) > 0) {				StorePacket();			}			m_possible.erase(m_possible.begin());		} else {			// Move to tried			m_tried[m_possible.begin()->first] = c;			// Send request			c->checkingType();			sendFindValue(c->getClientID(), c->getIPAddress(), c->getUDPPort());			break;		}	}	}void CSearch::processResponse(uint32 fromIP, uint16 fromPort, ContactList *results){	AddDebugLogLineM(false, logKadSearch, wxT("Process search response from ") + Uint32_16toStringIP_Port(wxUINT32_SWAP_ALWAYS(fromIP), fromPort));	if (results) {		m_lastResponse = time(NULL);	}	// Remember the contacts to be deleted when finished	ContactList::iterator response;	for (response = results->begin(); response != results->end(); ++response) {		m_delete.push_back(*response);	}	// Not interested in responses for FIND_NODE, will be added to contacts by udp listener	if (m_type == NODE) {		AddDebugLogLineM(false, logKadSearch, wxT("Node type search result, discarding."));		m_answers++;		m_possible.clear();		delete results;		return;	}	ContactMap::const_iterator tried;	CContact *c;	CContact *from;	CUInt128 distance;	CUInt128 fromDistance;	//Find contact that is responding.	for (tried = m_tried.begin(); tried != m_tried.end(); ++tried) {		fromDistance = tried->first;		from = tried->second;		if ((from->getIPAddress() == fromIP) && (from->getUDPPort() == fromPort)) {			// Add to list of people who responded			m_responded[fromDistance] = from;			// Loop through their responses			for (response = results->begin(); response != results->end(); ++response) {				c = *response;				distance = c->getClientID();				distance.XOR(m_target);				// Ignore this contact if already know him				if (m_possible.count(distance) > 0) {					// AddDebugLogLineM(false, logKadSearch, wxT("Search result from already known client: ignore"));					continue;				}				if (m_tried.count(distance) > 0) {					// AddDebugLogLineM(false, logKadSearch, wxT("Search result from already tried client: ignore"));					continue;				}								// Add to possible				m_possible[distance] = c;								if (distance < fromDistance) {					bool top = false;					if (m_best.size() < ALPHA_QUERY) {						top = true;						m_best[distance] = c;					} else {						ContactMap::iterator it = m_best.end();						--it;						if (distance < it->first) {							// Rotate best list							m_best.erase(it);							m_best[distance] = c;							top = true;						}					}										if (top) {						// Add to tried						m_tried[distance] = c;						// Send request						c->checkingType();						sendFindValue(c->getClientID(), c->getIPAddress(), c->getUDPPort());					}				}			}			// We don't want anything from these people, so just increment the counter.			if( m_type == NODECOMPLETE ) {				AddDebugLogLineM(false, logKadSearch, wxT("Search result type: Node complete"));				m_answers++;			}			break;		}	}		delete results;}void CSearch::StorePacket(){	wxASSERT(!m_possible.empty());		CContact *from;	CUInt128 fromDistance;	ContactMap::const_iterator possible;	possible = m_possible.begin();	fromDistance = possible->first;	from = possible->second;	if(thePrefs::FilterLanIPs() && fromDistance.get32BitChunk(0) > SEARCHTOLERANCE) {		AddDebugLogLineM(false, logKadSearch, wxT("Not stored: filtered lan ip"));		return;	}	switch(m_type) {		case FILE:		case KEYWORD: {			if (m_type == FILE) {				AddDebugLogLineM(false, logKadSearch, wxT("Search result type: File"));				AddDebugLogLineM(false, logClientKadUDP, wxT("KadSearchReq (File) ") + Uint32_16toStringIP_Port(wxUINT32_SWAP_ALWAYS(from->getIPAddress()), from->getUDPPort()));			} else {				AddDebugLogLineM(false, logKadSearch, wxT("Search result type: Keyword"));				AddDebugLogLineM(false, logClientKadUDP, wxT("KadSearchReq (Keyword) ") + Uint32_16toStringIP_Port(wxUINT32_SWAP_ALWAYS(from->getIPAddress()), from->getUDPPort()));			}			wxASSERT( m_searchTerms->GetLength() > 0 );			// The data in 'm_searchTerms' is to be sent several times, so use the don't detach flag.			CKademlia::getUDPListener()->sendPacket(m_searchTerms, KADEMLIA_SEARCH_REQ, from->getIPAddress(), from->getUDPPort());			m_totalRequestAnswers++;			break;		}		case NOTES: {			AddDebugLogLineM(false, logKadSearch, wxT("Search result type: Notes"));			CMemFile bio(34);			bio.WriteUInt128(m_target);			bio.WriteUInt128(CKademlia::getPrefs()->getKadID());			CKademlia::getUDPListener()->sendPacket( &bio, KADEMLIA_SRC_NOTES_REQ, from->getIPAddress(), from->getUDPPort());			m_totalRequestAnswers++;			break;		}		case STOREFILE: {			AddDebugLogLineM(false, logKadSearch, wxT("Search result type: StoreFile"));			if( m_answers > SEARCHSTOREFILE_TOTAL ) {				prepareToStop();				break;			}			byte fileid[16];			m_target.toByteArray(fileid);			CKnownFile* file = theApp.sharedfiles->GetFileByID(CMD4Hash(fileid));			if (file) {				m_fileName = file->GetFileName();				CUInt128 id(CKademlia::getPrefs()->getClientHash());				TagList taglist;				//We can use type for different types of sources. 				//1 is reserved for highID sources..				//2 cannot be used as older clients will not work.				//3 Firewalled Kad Source.					if( theApp.IsFirewalled() ) {					if( theApp.clientlist->GetBuddy() ) {						CUInt128 buddyID(true);						buddyID.XOR(CKademlia::getPrefs()->getKadID());						taglist.push_back(new CTagUInt8(TAG_SOURCETYPE, 3));						taglist.push_back(new CTagUInt32(TAG_SERVERIP, theApp.clientlist->GetBuddy()->GetIP()));						taglist.push_back(new CTagUInt16(TAG_SERVERPORT, theApp.clientlist->GetBuddy()->GetUDPPort()));						byte hashBytes[16];						buddyID.toByteArray(hashBytes);						taglist.push_back(new CTagStr(TAG_BUDDYHASH, CMD4Hash(hashBytes).Encode()));						taglist.push_back(new CTagUInt16(TAG_SOURCEPORT, thePrefs::GetPort()));					} else {						prepareToStop();						break;					}				} else {					taglist.push_back(new CTagUInt8(TAG_SOURCETYPE, 1));					taglist.push_back(new CTagUInt16(TAG_SOURCEPORT, thePrefs::GetPort()));				}				CKademlia::getUDPListener()->publishPacket(from->getIPAddress(), from->getUDPPort(),m_target,id, taglist);				m_totalRequestAnswers++;				TagList::const_iterator it;				for (it = taglist.begin(); it != taglist.end(); ++it) {					delete *it;				}			}			break;		}		case STOREKEYWORD: {			AddDebugLogLineM(false, logKadSearch, wxT("Search result type: StoreKeyword"));			if( m_answers > SEARCHSTOREKEYWORD_TOTAL ) {				prepareToStop();				break;			}			if( bio1 ) {				AddDebugLogLineM(false, logClientKadUDP, wxT("KadStoreKeywReq ") + Uint32_16toStringIP_Port(wxUINT32_SWAP_ALWAYS(from->getIPAddress()), from->getUDPPort()));												CKademlia::getUDPListener()->sendPacket( packet1, ((1024*50)-bio1->getAvailable()), from->getIPAddress(), from->getUDPPort() );			}			if( bio2 ) {				AddDebugLogLineM(false, logClientKadUDP, wxT("KadStoreKeywReq ") + Uint32_16toStringIP_Port(wxUINT32_SWAP_ALWAYS(from->getIPAddress()), from->getUDPPort()));															CKademlia::getUDPListener()->sendPacket( packet2, ((1024*50)-bio2->getAvailable()), from->getIPAddress(), from->getUDPPort() );			}			if( bio3 ) {				AddDebugLogLineM(false, logClientKadUDP, wxT("KadStoreKeywReq ")  + Uint32_16toStringIP_Port(wxUINT32_SWAP_ALWAYS(from->getIPAddress()), from->getUDPPort()));												CKademlia::getUDPListener()->sendPacket( packet3, ((1024*50)-bio3->getAvailable()), from->getIPAddress(), from->getUDPPort() );			}			m_totalRequestAnswers++;			break;		}		case STORENOTES: {			AddDebugLogLineM(false, logKadSearch, wxT("Search result type: StoreNotes"));			byte fileid[16];			m_target.toByteArray(fileid);			CKnownFile* file = theApp.sharedfiles->GetFileByID(CMD4Hash(fileid));			if (file) {				byte packet[1024*2];				CByteIO bio(packet,sizeof(packet));				bio.writeUInt128(m_target);				bio.writeUInt128(CKademlia::getPrefs()->getKadID());				uint8 tagcount = 1;				if(file->GetFileRating() != 0) {					++tagcount;				}				if(!file->GetFileComment().IsEmpty()) {					++tagcount;				}				//Number of tags.				bio.writeUInt8(tagcount);				CTagStr fileName(TAG_FILENAME, file->GetFileName());				bio.writeTag(&fileName);				if(file->GetFileRating() != 0) {					CTagUInt16 rating(TAG_FILERATING, file->GetFileRating());					bio.writeTag(&rating);				}				if(!file->GetFileComment().IsEmpty()) {					CTagStr description(TAG_DESCRIPTION, file->GetFileComment());					bio.writeTag(&description);				}				CKademlia::getUDPListener()->sendPacket( packet, sizeof(packet)-bio.getAvailable(), KADEMLIA_PUB_NOTES_REQ, from->getIPAddress(), from->getUDPPort());				m_totalRequestAnswers++;			}			break;		}		case FINDBUDDY:		{			AddDebugLogLineM(false, logKadSearch, wxT("Search result type: FindBuddy"));			if( m_answers > SEARCHFINDBUDDY_TOTAL ) {				prepareToStop();				break;			}			CMemFile bio(34);			bio.WriteUInt128(m_target);			bio.WriteUInt128(CKademlia::getPrefs()->getClientHash());			bio.WriteUInt16(thePrefs::GetPort());			CKademlia::getUDPListener()->sendPacket( &bio, KADEMLIA_FINDBUDDY_REQ, from->getIPAddress(), from->getUDPPort());			m_answers++;			break;		}		case FINDSOURCE:		{			AddDebugLogLineM(false, logKadSearch, wxT("Search result type: FindSource"));			if( m_answers > SEARCHFINDSOURCE_TOTAL ) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -