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

📄 kademliaudplistener.cpp

📁 非常难得的eMule(电骡) V0.45b 源码下载 值得研究
💻 CPP
📖 第 1 页 / 共 3 页
字号:
					}
					else if (!tag->m_name.Compare(TAG_SOURCEPORT))
					{
						if( entry->tcpport == 0 )
						{
							entry->tcpport = tag->GetInt();
							entry->taglist.push_back(tag);
						}
						else
						{
							//More then one port tag found
							delete tag;
						}
					}
					else
					{
						//TODO: Filter tags
						entry->taglist.push_back(tag);
					}
				}
				tags--;
			}
			if (bDbgInfo && !strInfo.IsEmpty())
				Debug(_T("%s\n"), strInfo);
		}
		catch(...)
		{
			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 )
	{
		CSafeMemFile bio2(17);
		bio2.WriteUInt128(&file);
		bio2.WriteUInt8(load);
		if (thePrefs.GetDebugClientKadUDPLevel() > 0)
			DebugSend("KadPublishRes", ip, port);

		sendPacket( &bio2, KADEMLIA_PUBLISH_RES, ip, port);
	}
}

//KADEMLIA_PUBLISH_ACK
void CKademliaUDPListener::processPublishResponse (const byte *packetData, uint32 lenPacket, uint32 ip, uint16 port)
{
	// Verify packet is expected size
	if (lenPacket < 16){
		CString strError;
		strError.Format(_T("***NOTE: Received wrong size (%u) packet in %hs"), lenPacket, __FUNCTION__);
		throw strError;
	}

	// Set contact to alive.
	CKademlia::getRoutingZone()->setAlive(ip, port);

	CSafeMemFile bio(packetData, lenPacket);
	CUInt128 file;
	bio.ReadUInt128(&file);

	bool loadResponse = false;
	uint8 load = 0;
	if( bio.GetLength() > bio.GetPosition() )
	{
		loadResponse = true;
		load = bio.ReadUInt8();
	}

	CSearchManager::processPublishResult(file, load, loadResponse);
}

//KADEMLIA_SRC_NOTES_REQ
void CKademliaUDPListener::processSearchNotesRequest (const byte *packetData, uint32 lenPacket, uint32 ip, uint16 port)
{
	// Verify packet is expected size
	if (lenPacket < 32)
	{
		CString strError;
		strError.Format(_T("***NOTE: Received wrong size (%u) packet in %hs"), lenPacket, __FUNCTION__);
		throw strError;
	}

	CSafeMemFile bio( packetData, lenPacket);
	CUInt128 target;
	bio.ReadUInt128(&target);
	CUInt128 source;
	bio.ReadUInt128(&source);

	CKademlia::getIndexed()->SendValidNoteResult(target, source, ip, port);
}

//KADEMLIA_SRC_NOTES_RES
void CKademliaUDPListener::processSearchNotesResponse (const byte *packetData, uint32 lenPacket, uint32 ip, uint16 port)
{
	// Verify packet is expected size
	if (lenPacket < 37){
		CString strError;
		strError.Format(_T("***NOTE: Received wrong size (%u) packet in %hs"), lenPacket, __FUNCTION__);
		throw strError;
	}

	// 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(...){
			deleteTagListEntries(tags);
			delete tags;
			tags = NULL;
			throw;
		}
		CSearchManager::processResult(target, ip, port, answer, tags);
		count--;
	}
}

//KADEMLIA_PUB_NOTES_REQ
void CKademliaUDPListener::processPublishNotesRequest (const byte *packetData, uint32 lenPacket, uint32 ip, uint16 port)
{
	// Verify packet is expected size
	if (lenPacket < 37){
		CString strError;
		strError.Format(_T("***NOTE: Received wrong size (%u) packet in %hs"), lenPacket, __FUNCTION__);
		throw strError;
	}

	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);
	distance.xor(target);

	if( thePrefs.FilterLANIPs() && distance.get32BitChunk(0) > SEARCHTOLERANCE)
		return;

	//bool bDbgInfo = thePrefs.GetDebugClientKadUDPLevel() > 0;

	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(...)
	{
		delete entry;
		throw;
	}

	if( entry == NULL )
	{
		throw CString(_T("CKademliaUDPListener::processPublishNotesRequest: entry == NULL"));
	}
	else if( entry->taglist.size() == 0 || entry->taglist.size() > 5)
	{
		delete entry;
		throw CString(_T("CKademliaUDPListener::processPublishNotesRequest: entry->taglist.size() == 0 || entry->taglist.size() > 5"));
	}

	uint8 load = 0;
	if( CKademlia::getIndexed()->AddNotes(target, source, entry, load ) )
	{
		CSafeMemFile bio2(17);
		bio2.WriteUInt128(&target);
		bio2.WriteUInt8(load);
		if (thePrefs.GetDebugClientKadUDPLevel() > 0)
			DebugSend("KadPublishNotesRes", ip, port);

		sendPacket( &bio2, KADEMLIA_PUB_NOTES_RES, ip, port);
	}
	else
		delete entry;
}

//KADEMLIA_PUB_NOTES_RES
void CKademliaUDPListener::processPublishNotesResponse (const byte *packetData, uint32 lenPacket, uint32 ip, uint16 port)
{
	// Verify packet is expected size
	if (lenPacket < 16){
		CString strError;
		strError.Format(_T("***NOTE: Received wrong size (%u) packet in %hs"), lenPacket, __FUNCTION__);
		throw strError;
	}

	// Set contact to alive.
	CKademlia::getRoutingZone()->setAlive(ip, port);

	CSafeMemFile bio(packetData, lenPacket);
	CUInt128 file;
	bio.ReadUInt128(&file);

	bool loadResponse = false;
	uint8 load = 0;
	if( bio.GetLength() > bio.GetPosition() )
	{
		loadResponse = true;
		load = bio.ReadUInt8();
	}

	CSearchManager::processPublishResult(file, load, loadResponse);
}

//KADEMLIA_FIREWALLED_REQ
void CKademliaUDPListener::processFirewalledRequest (const byte *packetData, uint32 lenPacket, uint32 ip, uint16 port)
{
	// Verify packet is expected size
	if (lenPacket != 2){
		CString strError;
		strError.Format(_T("***NOTE: Received wrong size (%u) packet in %hs"), lenPacket, __FUNCTION__);
		throw strError;
	}

	CSafeMemFile bio(packetData, lenPacket);
	uint16 tcpport = bio.ReadUInt16();

	CContact contact;
	contact.setIPAddress(ip);
	contact.setTCPPort(tcpport);
	contact.setUDPPort(port);
	theApp.clientlist->RequestTCP(&contact);

	// Send response
	CSafeMemFile bio2(4);
	bio2.WriteUInt32(ip);
	if (thePrefs.GetDebugClientKadUDPLevel() > 0)
		DebugSend("KadFirewalledRes", ip, port);

	sendPacket(&bio2, KADEMLIA_FIREWALLED_RES, ip, port);
}

//KADEMLIA_FIREWALLED_RES
void CKademliaUDPListener::processFirewalledResponse (const byte *packetData, uint32 lenPacket, uint32 ip, uint16 port)
{
	// Verify packet is expected size
	if (lenPacket != 4){
		CString strError;
		strError.Format(_T("***NOTE: Received wrong size (%u) packet in %hs"), lenPacket, __FUNCTION__);
		throw strError;
	}

	// Set contact to alive.
	CKademlia::getRoutingZone()->setAlive(ip, port);

	CSafeMemFile bio(packetData, lenPacket);
	uint32 firewalledIP = bio.ReadUInt32();

	//Update con state only if something changes.
	if( CKademlia::getPrefs()->getIPAddress() != firewalledIP )
	{
		CKademlia::getPrefs()->setIPAddress(firewalledIP);
		theApp.emuledlg->ShowConnectionState();
	}
	CKademlia::getPrefs()->incRecheckIP();
}

//KADEMLIA_FIREWALLED_ACK
void CKademliaUDPListener::processFirewalledResponse2 (const byte *packetData, uint32 lenPacket, uint32 ip, uint16 port)
{
	// Verify packet is expected size
	if (lenPacket != 0){
		CString strError;
		strError.Format(_T("***NOTE: Received wrong size (%u) packet in %hs"), lenPacket, __FUNCTION__);
		throw strError;
	}

	// Set contact to alive.
	CKademlia::getRoutingZone()->setAlive(ip, port);

	CKademlia::getPrefs()->incFirewalled();
}

//KADEMLIA_FINDBUDDY_REQ
void CKademliaUDPListener::processFindBuddyRequest (const byte *packetData, uint32 lenPacket, uint32 ip, uint16 port)
{
	// Verify packet is expected size
	if (lenPacket < 34){
		CString strError;
		strError.Format(_T("***NOTE: Received wrong size (%u) packet in %hs"), lenPacket, __FUNCTION__);
		throw strError;
	}

	if( CKademlia::getPrefs()->getFirewalled() )
		//We are firewalled but somehow we still got this packet.. Don't send a response..
		return;

	CSafeMemFile bio(packetData, lenPacket);
	CUInt128 BuddyID;
	bio.ReadUInt128(&BuddyID);
	CUInt128 userID;
	bio.ReadUInt128(&userID);
	uint16 tcpport = bio.ReadUInt16();

	CContact contact;
	contact.setIPAddress(ip);
	contact.setTCPPort(tcpport);
	contact.setUDPPort(port);
	contact.setClientID(userID);
	theApp.clientlist->IncomingBuddy(&contact, &BuddyID);

	CSafeMemFile bio2(34);
	bio2.WriteUInt128(&BuddyID);
	bio2.WriteUInt128(&CKademlia::getPrefs()->getClientHash());
	bio2.WriteUInt16(thePrefs.GetPort());
	if (thePrefs.GetDebugClientKadUDPLevel() > 0)
		DebugSend("KadFindBuddyRes", ip, port);

	sendPacket(&bio2, KADEMLIA_FINDBUDDY_RES, ip, port);
}

//KADEMLIA_FINDBUDDY_RES
void CKademliaUDPListener::processFindBuddyResponse (const byte *packetData, uint32 lenPacket, uint32 ip, uint16 port)
{
	// Verify packet is expected size
	if (lenPacket < 34){
		CString strError;
		strError.Format(_T("***NOTE: Received wrong size (%u) packet in %hs"), lenPacket, __FUNCTION__);
		throw strError;
	}


	CSafeMemFile bio(packetData, lenPacket);
	CUInt128 check;
	bio.ReadUInt128(&check);
	check.xor(CUInt128(true));
	if( CKademlia::getPrefs()->getKadID().compareTo(check))
		return;
	CUInt128 userID;
	bio.ReadUInt128(&userID);
	uint16 tcpport = bio.ReadUInt16();

	CContact contact;
	contact.setIPAddress(ip);
	contact.setTCPPort(tcpport);
	contact.setUDPPort(port);
	contact.setClientID(userID);
	theApp.clientlist->RequestBuddy(&contact);
}

//KADEMLIA_FINDSOURCE_REQ
void CKademliaUDPListener::processFindSourceRequest (const byte *packetData, uint32 lenPacket, uint32 ip, uint16 port)
{
	// Verify packet is expected size
	if (lenPacket < 34){
		CString strError;
		strError.Format(_T("***NOTE: Received wrong size (%u) packet in %hs"), lenPacket, __FUNCTION__);
		throw strError;
	}

	CUpDownClient* buddy = theApp.clientlist->GetBuddy();
	if( buddy != NULL )
	{
		CSafeMemFile bio(packetData, lenPacket);
		CUInt128 check;
		bio.ReadUInt128(&check);
		CUInt128 bud(buddy->GetBuddyID());
		CUInt128 file;
		bio.ReadUInt128(&file);
		uint16 tcp = bio.ReadUInt16();
		CSafeMemFile bio2(lenPacket+6);
		bio2.WriteUInt128(&check);
		bio2.WriteUInt128(&file);
		bio2.WriteUInt32(ip);
		bio2.WriteUInt16(tcp);
		Packet* packet = new Packet(&bio2, OP_EMULEPROT, OP_CALLBACK);
		if( buddy->socket )
            buddy->socket->SendPacket(packet);
		else
			ASSERT(0);
		if (thePrefs.GetDebugClientKadUDPLevel() > 0)
			DebugSend("KadCallback", ip, port);
	}
}

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.
	Packet* packet = new Packet(OP_KADEMLIAHEADER);
	packet->opcode = data[1];
	packet->pBuffer = new char[lenData+8];
	memcpy(packet->pBuffer, data+2, lenData-2);
	packet->size = lenData-2;
	if( lenData > 200 )
		packet->PackPacket();
	theStats.AddUpDataOverheadKad(packet->size);
	theApp.clientudp->SendPacket(packet, ntohl(destinationHost), destinationPort);
}

void CKademliaUDPListener::sendPacket(const byte *data, uint32 lenData, byte opcode, uint32 destinationHost, uint16 destinationPort)
{
	Packet* packet = new Packet(OP_KADEMLIAHEADER);
	packet->opcode = opcode;
	packet->pBuffer = new char[lenData];
	memcpy(packet->pBuffer, data, lenData);
	packet->size = lenData;
	if( lenData > 200 )
		packet->PackPacket();
	theStats.AddUpDataOverheadKad(packet->size);
	theApp.clientudp->SendPacket(packet, ntohl(destinationHost), destinationPort);
}

void CKademliaUDPListener::sendPacket(CSafeMemFile *data, byte opcode, uint32 destinationHost, uint16 destinationPort)
{
	Packet* packet = new Packet(data, OP_KADEMLIAHEADER);
	packet->opcode = opcode;
	if( packet->size > 200 )
		packet->PackPacket();
	theStats.AddUpDataOverheadKad(packet->size);
	theApp.clientudp->SendPacket(packet, ntohl(destinationHost), destinationPort);
}

⌨️ 快捷键说明

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