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

📄 kademliaudplistener.cpp

📁 电驴的源代码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
						}
						else
						{
							//More then one size tag found
							delete tag;
						}
					}
					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 )
		{
			if( indexed->AddSources(file, target, entry, load ) )
				flag = true;
			else
			{
				delete entry;
				entry = NULL;
			}
		}
		else
		{
			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;
	}

	//Used Pointers
	CRoutingZone *routingZone = CKademlia::getRoutingZone();
	ASSERT(routingZone != NULL); 

	// Set contact to alive.
	routingZone->setAlive(ip, port);

	CSafeMemFile bio(packetData, lenPacket);
	CUInt128 file;
	bio.ReadUInt128(&file);
	CSearchManager::processPublishResult(file);
}

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

	//Used Pointers
	CIndexed *indexed = CKademlia::getIndexed();
	ASSERT(indexed != NULL); 

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

	indexed->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;
	}

	//Used Pointers
	CRoutingZone *routingZone = CKademlia::getRoutingZone();
	ASSERT(routingZone != NULL); 

	// Set contact to alive.
	routingZone->setAlive(ip, port);

	// What search does this relate to
	CByteIO bio(packetData, lenPacket);
	CUInt128 target;
	bio.readUInt128(&target);

	// How many results.. Not supported yet..
	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 = bio.readTagList(true/*bOptACP*/);
		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;
	}

	//Used Pointers
	CIndexed *indexed = CKademlia::getIndexed();
	ASSERT(indexed != NULL);
	CPrefs *prefs = CKademlia::getPrefs();
	ASSERT(prefs != NULL); 

	if( prefs->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;
	prefs->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);
		uint32 tags = bio.readByte();
		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() > 2)
	{
		delete entry;
		throw CString(_T("CKademliaUDPListener::processPublishNotesRequest: entry->taglist.size() == 0 || entry->taglist.size() > 2"));
	}

	if( indexed->AddNotes(target, source, entry ) )
	{
		CSafeMemFile bio2(16);
		bio2.WriteUInt128(&target);
		if (thePrefs.GetDebugClientKadUDPLevel() > 0)
			DebugSend("KadPublishNotesRes", ip, port);

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

//KADEMLIA_PUB_NOTES_ACK
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;
	}
	//Used Pointers
	CRoutingZone *routingZone = CKademlia::getRoutingZone();
	ASSERT(routingZone != NULL); 

	// Set contact to alive.
	routingZone->setAlive(ip, port);
}

//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;
	}

	//Used Pointers
	CRoutingZone *routingZone = CKademlia::getRoutingZone();
	ASSERT(routingZone != NULL); 

	// Set contact to alive.
	routingZone->setAlive(ip, port);

	CSafeMemFile bio(packetData, lenPacket);
	uint32 firewalledIP = bio.ReadUInt32();
	CPrefs *prefs = CKademlia::getPrefs();
	ASSERT(prefs != NULL);

	//Update con state only if something changes.
	if( prefs->getIPAddress() != firewalledIP )
	{
		prefs->setIPAddress(firewalledIP);
		theApp.emuledlg->ShowConnectionState();
	}
	prefs->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;
	}

	//Used Pointers
	CPrefs *prefs = CKademlia::getPrefs();
	ASSERT(prefs != NULL); 
	CRoutingZone *routingZone = CKademlia::getRoutingZone();
	ASSERT(routingZone != NULL); 

	// Set contact to alive.
	routingZone->setAlive(ip, port);

	prefs->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;
	}

	//Used Pointers
	CPrefs *prefs = CKademlia::getPrefs();
	ASSERT(prefs != NULL); 

	if( prefs->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(&prefs->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;
	}

	//Used Pointers
	CPrefs *prefs = CKademlia::getPrefs();
	ASSERT(prefs != NULL);

	CSafeMemFile bio(packetData, lenPacket);
	CUInt128 check;
	bio.ReadUInt128(&check);
	check.xor(CUInt128(true));
	if( prefs->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;
	}

	//Used Pointers
	CPrefs *prefs = CKademlia::getPrefs();
	ASSERT(prefs != NULL);

	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 + -