kademliaudplistener.cpp

来自「wxWidgets写的电驴」· C++ 代码 · 共 1,226 行 · 第 1/3 页

CPP
1,226
字号
					} else {						//TODO: Filter tags						entry->taglist.push_back(tag);					}				}				tags--;			}			if (!strInfo.IsEmpty()) {				AddDebugLogLineM(false, logClientKadUDP, strInfo);			}		} catch(...) {			DebugClientOutput(wxT("CKademliaUDPListener::processPublishRequest"),ip,port);			delete entry;			throw;		}		if( entry->source == true ) {			entry->lifetime = (uint32)time(NULL)+KADEMLIAREPUBLISHTIMES;			if( indexed->AddSources(file, target, entry, load ) ) {				flag = true;			} else {				delete entry;				entry = NULL;			}		} else {			entry->lifetime = (uint32)time(NULL)+KADEMLIAREPUBLISHTIMEK;			if( indexed->AddKeyword(file, target, entry, load) ) {				// This makes sure we send a publish response.. 				// This also makes sure we index all the files for this keyword.				flag = true;			} else {				//We already indexed the maximum number of keywords.				//We do not index anymore but we still send a success..				//Reason: Because if a VERY busy node tells the publisher it failed,				//this busy node will spread to all the surrounding nodes causing popular				//keywords to be stored on MANY nodes..				//So, once we are full, we will periodically clean our list until we can				//begin storing again..				flag = true;				delete entry;				entry = NULL;			}		}		count--;	}		if( flag ) {		CMemFile bio2(17);		bio2.WriteUInt128(file);		bio2.WriteUInt8(load);		AddDebugLogLineM(false, logClientKadUDP, CFormat(wxT("KadPublishRes %s")) % Uint32_16toStringIP_Port(wxUINT32_SWAP_ALWAYS(ip), port));		sendPacket( &bio2, KADEMLIA_PUBLISH_RES, ip, port);	}}//KADEMLIA_PUBLISH_ACKvoid CKademliaUDPListener::processPublishResponse (const byte *packetData, uint32 lenPacket, uint32 ip, uint16 port){	// Verify packet is expected size	if (lenPacket < 16) {		throw wxString::Format(wxT("***NOTE: Received wrong size (%u) packet in "), lenPacket) + wxString::FromAscii(__FUNCTION__);	}	// Set contact to alive.	CKademlia::getRoutingZone()->setAlive(ip, port);	CMemFile bio((byte*)packetData, lenPacket);	CUInt128 file = bio.ReadUInt128();	bool loadResponse = false;	uint8 load = 0;	if( bio.GetLength() > bio.GetPosition() ) {		loadResponse = true;		load = bio.ReadUInt8();	}	CSearchManager::processPublishResult(file, load, loadResponse);}//KADEMLIA_SRC_NOTES_REQvoid CKademliaUDPListener::processSearchNotesRequest (const byte *packetData, uint32 lenPacket, uint32 ip, uint16 port){	// Verify packet is expected size	if (lenPacket < 32) {		throw wxString::Format(wxT("***NOTE: Received wrong size (%u) packet in "), lenPacket) + wxString::FromAscii(__FUNCTION__);	}	CMemFile bio((byte*)packetData, lenPacket);	CUInt128 target = bio.ReadUInt128();	CUInt128 source = bio.ReadUInt128();	CKademlia::getIndexed()->SendValidNoteResult(target, source, ip, port);}//KADEMLIA_SRC_NOTES_RESvoid CKademliaUDPListener::processSearchNotesResponse (const byte *packetData, uint32 lenPacket, uint32 ip, uint16 port){	// Verify packet is expected size	if (lenPacket < 37) {		throw wxString::Format(wxT("***NOTE: Received wrong size (%u) packet in "), lenPacket) + wxString::FromAscii(__FUNCTION__);	}	// Set contact to alive.	CKademlia::getRoutingZone()->setAlive(ip, port);	// What search does this relate to	CByteIO bio(packetData, lenPacket);	CUInt128 target;	bio.readUInt128(&target);	uint16 count = bio.readUInt16();	while( count > 0 ) {		// What is the answer		CUInt128 answer;		bio.readUInt128(&answer);		// Get info about answer		// NOTE: this is the one and only place in Kad where we allow string conversion to local code page in		// case we did not receive an UTF8 string. this is for backward compatibility for search results which are 		// supposed to be 'viewed' by user only and not feed into the Kad engine again!		// If that tag list is once used for something else than for viewing, special care has to be taken for any		// string conversion!		TagList* tags = new TagList;		try{			bio.readTagList(tags, true/*bOptACP*/);		} catch(...){			DebugClientOutput(wxT("CKademliaUDPListener::processSearchNotesResponse"),ip,port);			deleteTagListEntries(tags);			delete tags;			tags = NULL;			throw;		}		CSearchManager::processResult(target, ip, port, answer, tags);		count--;	}}//KADEMLIA_PUB_NOTES_REQvoid CKademliaUDPListener::processPublishNotesRequest (const byte *packetData, uint32 lenPacket, uint32 ip, uint16 port){	// Verify packet is expected size	if (lenPacket < 37) {		throw wxString::Format(wxT("***NOTE: Received wrong size (%u) packet in "), lenPacket) + wxString::FromAscii(__FUNCTION__);	}	if( CKademlia::getPrefs()->getFirewalled() ) {		//We are firewalled. We should not index this entry and give publisher a false report.		return;	}	CByteIO bio(packetData, lenPacket);	CUInt128 target;	bio.readUInt128(&target);	CUInt128 distance(CKademlia::getPrefs()->getKadID());	distance.XOR(target);	if( thePrefs::FilterLanIPs() && distance.get32BitChunk(0) > SEARCHTOLERANCE) {		return;	}	CUInt128 source;	bio.readUInt128(&source);	Kademlia::CEntry* entry = new Kademlia::CEntry();	try {		entry->ip = ip;		entry->udpport = port;		entry->keyID.setValue(target);		entry->sourceID.setValue(source);		bio.readTagList(&entry->taglist);		entry->source = false;	} catch(...) {		DebugClientOutput(wxT("CKademliaUDPListener::processPublishNotesRequest"),ip,port);		delete entry;		throw;	}	if( entry == NULL ) {		throw wxString(wxT("CKademliaUDPListener::processPublishNotesRequest: entry == NULL"));	} else if( entry->taglist.size() == 0 || entry->taglist.size() > 5) {		delete entry;		throw wxString(wxT("CKademliaUDPListener::processPublishNotesRequest: entry->taglist.size() == 0 || entry->taglist.size() > 5"));	}	uint8 load = 0;	if( CKademlia::getIndexed()->AddNotes(target, source, entry, load ) ) {		CMemFile bio2(17);		bio2.WriteUInt128(target);		bio2.WriteUInt8(load);		AddDebugLogLineM(false, logClientKadUDP, CFormat(wxT("KadPublishNotesRes %s")) % Uint32_16toStringIP_Port(wxUINT32_SWAP_ALWAYS(ip), port));		sendPacket( &bio2, KADEMLIA_PUB_NOTES_RES, ip, port);	} else {		delete entry;	}}//KADEMLIA_PUB_NOTES_RESvoid CKademliaUDPListener::processPublishNotesResponse (const byte *packetData, uint32 lenPacket, uint32 ip, uint16 port){	// Verify packet is expected size	if (lenPacket < 16){		throw wxString::Format(wxT("***NOTE: Received wrong size (%u) packet in "), lenPacket) + wxString::FromAscii(__FUNCTION__);			}	// Set contact to alive.	CKademlia::getRoutingZone()->setAlive(ip, port);	CMemFile bio((byte*)packetData, lenPacket);	CUInt128 file = bio.ReadUInt128();	bool loadResponse = false;	uint8 load = 0;	if( bio.GetLength() > bio.GetPosition() ) {		loadResponse = true;		load = bio.ReadUInt8();	}	CSearchManager::processPublishResult(file, load, loadResponse);}//KADEMLIA_FIREWALLED_REQvoid CKademliaUDPListener::processFirewalledRequest (const byte *packetData, uint32 lenPacket, uint32 ip, uint16 port){	// Verify packet is expected size	if (lenPacket != 2){		throw wxString::Format(wxT("***NOTE: Received wrong size (%u) packet in "), lenPacket) + wxString::FromAscii(__FUNCTION__);	}	CMemFile bio((byte*)packetData, lenPacket);	uint16 tcpport = bio.ReadUInt16();	CContact contact;	contact.setIPAddress(ip);	contact.setTCPPort(tcpport);	contact.setUDPPort(port);	theApp.clientlist->RequestTCP(&contact);	// Send response	CMemFile bio2(4);	bio2.WriteUInt32(ip);	AddDebugLogLineM(false, logClientKadUDP, CFormat(wxT("KadFirewalledRes %s")) % Uint32_16toStringIP_Port(wxUINT32_SWAP_ALWAYS(ip), port));	sendPacket(&bio2, KADEMLIA_FIREWALLED_RES, ip, port);}//KADEMLIA_FIREWALLED_RESvoid CKademliaUDPListener::processFirewalledResponse (const byte *packetData, uint32 lenPacket, uint32 ip, uint16 port){	// Verify packet is expected size	if (lenPacket != 4){		throw wxString::Format(wxT("***NOTE: Received wrong size (%u) packet in "), lenPacket) + wxString::FromAscii(__FUNCTION__);	}	// Set contact to alive.	CKademlia::getRoutingZone()->setAlive(ip, port);	CMemFile bio((byte*)packetData, lenPacket);	uint32 firewalledIP = bio.ReadUInt32();	//Update con state only if something changes.	if( CKademlia::getPrefs()->getIPAddress() != firewalledIP ) {		CKademlia::getPrefs()->setIPAddress(firewalledIP);		theApp.ShowConnectionState();	}	CKademlia::getPrefs()->incRecheckIP();}//KADEMLIA_FIREWALLED_ACKvoid CKademliaUDPListener::processFirewalledResponse2 (const byte *WXUNUSED(packetData), uint32 lenPacket, uint32 ip, uint16 port){	// Verify packet is expected size	if (lenPacket != 0) {		throw wxString::Format(wxT("***NOTE: Received wrong size (%u) packet in "), lenPacket) + wxString::FromAscii(__FUNCTION__);	}	// Set contact to alive.	CKademlia::getRoutingZone()->setAlive(ip, port);	CKademlia::getPrefs()->incFirewalled();}//KADEMLIA_FINDBUDDY_REQvoid CKademliaUDPListener::processFindBuddyRequest (const byte *packetData, uint32 lenPacket, uint32 ip, uint16 port){	// Verify packet is expected size	if (lenPacket < 34) {		throw wxString::Format(wxT("***NOTE: Received wrong size (%u) packet in "), lenPacket) + wxString::FromAscii(__FUNCTION__);	}	if( CKademlia::getPrefs()->getFirewalled() ) {		//We are firewalled but somehow we still got this packet.. Don't send a response..		return;	}	CMemFile bio((byte*)packetData, lenPacket);	CUInt128 BuddyID = bio.ReadUInt128();	CUInt128 userID = bio.ReadUInt128();	uint16 tcpport = bio.ReadUInt16();	CContact contact;	contact.setIPAddress(ip);	contact.setTCPPort(tcpport);	contact.setUDPPort(port);	contact.setClientID(userID);	theApp.clientlist->IncomingBuddy(&contact, &BuddyID);	CMemFile bio2(34);	bio2.WriteUInt128(BuddyID);	bio2.WriteUInt128(CKademlia::getPrefs()->getClientHash());	bio2.WriteUInt16(thePrefs::GetPort());	AddDebugLogLineM(false, logClientKadUDP, CFormat(wxT("KadFindBuddyRes %s")) % Uint32_16toStringIP_Port(wxUINT32_SWAP_ALWAYS(ip), port));	sendPacket(&bio2, KADEMLIA_FINDBUDDY_RES, ip, port);}//KADEMLIA_FINDBUDDY_RESvoid CKademliaUDPListener::processFindBuddyResponse (const byte *packetData, uint32 lenPacket, uint32 ip, uint16 port){	// Verify packet is expected size	if (lenPacket < 34) {		throw wxString::Format(wxT("***NOTE: Received wrong size (%u) packet in "), lenPacket) + wxString::FromAscii(__FUNCTION__);	}	CMemFile bio((byte*)packetData, lenPacket);	CUInt128 check = bio.ReadUInt128();	check.XOR(CUInt128(true));	if( CKademlia::getPrefs()->getKadID().compareTo(check)) {		return;	}	CUInt128 userID = bio.ReadUInt128();	uint16 tcpport = bio.ReadUInt16();	CContact contact;	contact.setIPAddress(ip);	contact.setTCPPort(tcpport);	contact.setUDPPort(port);	contact.setClientID(userID);	theApp.clientlist->RequestBuddy(&contact);}//KADEMLIA_CALLBACK_REQvoid CKademliaUDPListener::processCallbackRequest (const byte *packetData, uint32 lenPacket, uint32 ip, uint16 port){	// Verify packet is expected size	if (lenPacket < 34) {		throw wxString::Format(wxT("***NOTE: Received wrong size (%u) packet in "), lenPacket) + wxString::FromAscii(__FUNCTION__);	}	CUpDownClient* buddy = theApp.clientlist->GetBuddy();	if( buddy != NULL ) {		CMemFile bio((byte*)packetData, lenPacket);		CUInt128 check = bio.ReadUInt128();		// JOHNTODO: Filter bad buddies		//CUInt128 bud(buddy->GetBuddyID());		CUInt128 file = bio.ReadUInt128();		uint16 tcp = bio.ReadUInt16();		CMemFile bio2(lenPacket+6);		bio2.WriteUInt128(check);		bio2.WriteUInt128(file);		bio2.WriteUInt32(ip);		bio2.WriteUInt16(tcp);		CPacket* packet = new CPacket(&bio2, OP_EMULEPROT, OP_CALLBACK);		if( buddy->GetSocket() ) {			AddDebugLogLineM(false, logClientKadUDP, CFormat(wxT("KadCallback %s")) % Uint32_16toStringIP_Port(wxUINT32_SWAP_ALWAYS(ip), port));			theStats::AddUpOverheadFileRequest(packet->GetPacketSize());          	buddy->GetSocket()->SendPacket(packet);		} else {			wxASSERT(0);		}	}}void CKademliaUDPListener::sendPacket(const byte *data, uint32 lenData, uint32 destinationHost, uint16 destinationPort){	//This is temp.. The entire Kad code will be rewritten using CMemFile and send a Packet object directly.	CMemFile mem_data((byte*)data+2,lenData-2);		sendPacket(&mem_data,data[1],destinationHost, destinationPort);}void CKademliaUDPListener::sendPacket(const byte *data, uint32 lenData, byte opcode, uint32 destinationHost, uint16 destinationPort){	CMemFile mem_data((byte*)data,lenData);	sendPacket(&mem_data,opcode,destinationHost, destinationPort);}void CKademliaUDPListener::sendPacket(CMemFile *data, byte opcode, uint32 destinationHost, uint16 destinationPort){	CPacket* packet = new CPacket(data, OP_KADEMLIAHEADER, opcode);	if( packet->GetPacketSize() > 200 ) {		packet->PackPacket();	}	theStats::AddUpOverheadKad(packet->GetPacketSize());	theApp.clientudp->SendPacket(packet,wxUINT32_SWAP_ALWAYS(destinationHost), destinationPort);}void CKademliaUDPListener::DebugClientOutput(const wxString& place, uint32 ip, uint32 port) {	printf("Error on %s received from: %s\n",(const char*)unicode2char(place),(const char*)unicode2char(Uint32_16toStringIP_Port(ip,port)));	CClientList::SourceList clientslist = theApp.clientlist->GetClientsByIP(ip);	if (!clientslist.empty()) {		for (CClientList::SourceList::iterator it = clientslist.begin(); it != clientslist.end(); ++it) {			printf("Ip Matches: %s\n",(const char*)unicode2char((*it)->GetClientFullInfo()));		}	} else {		printf("No ip match\n");	}}

⌨️ 快捷键说明

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