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

📄 kademliaudplistener.cpp

📁 Kademlia---第第3代P2P原代码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
		CRoutingZone *routingZone = CKademlia::getRoutingZone();
		ASSERT(routingZone != NULL); 

		// Set contact to alive.
		routingZone->setAlive(ntohl(senderAddress->sin_addr.s_addr), ntohs(senderAddress->sin_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
			TagList *tags = bio.readTagList();

			CSearchManager::processResult(	target, 
											ntohl(senderAddress->sin_addr.s_addr), ntohs(senderAddress->sin_port), 
											answer,
											tags);

			count = count - 1;

		}
	} catch (...) {TRACE("Exception in Kademlia Search Response\n");}
}

//KADEMLIA_PUBLISH_REQ
void CKademliaUDPListener::processPublishRequest (const byte *packetData, const uint32 lenPacket, const sockaddr_in *senderAddress)
{
	//There are different types of publishing..
	//Keyword and File are Stored..
	try
	{
		if (lenPacket < 37){
			ASSERT(0);
			return;
		}

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

		CByteIO bio(packetData, lenPacket);
		CUInt128 file;
		bio.readUInt128(&file);

		CUInt128 distance;
		prefs->getClientID(&distance);
		distance.xor(file);

		CString dist;
		distance.toBinaryString(&dist);
		if(dist.Left(5) != "00000")
			return;
		// How many results.. Not supported yet..
		uint16 count = bio.readUInt16();
		while( count > 0 )
		{
			CUInt128 target;
			bio.readUInt128(&target);
	
			Kademlia::CEntry* entry = new Kademlia::CEntry();
			entry->ip = ntohl(senderAddress->sin_addr.s_addr);
			entry->udpport = ntohs(senderAddress->sin_port);
			entry->keyID.setValue(file);
			entry->sourceID.setValue(target);
			//uint32 tags = bio.readUInt32LE();
			uint32 tags = bio.readByte();
			while(tags > 0)
			{
				CTag* tag = bio.readTag();
				if (!tag->m_name.Compare(TAG_SOURCETYPE) && tag->m_type == 9) // 9 means UInt8
				{
					if( entry->source == false )
					{
						entry->taglist.push_back(new CTagUInt32(TAG_SOURCEIP, entry->ip));
						entry->taglist.push_back(new CTagUInt16(TAG_SOURCEUPORT, entry->udpport));
					}
					entry->source = true;
				}
				
				if (!tag->m_name.Compare(TAG_NAME)){
					entry->fileName = tag->GetStr();
					// NOTE: always add the 'name' tag, even if it's stored separately in 'fileName'. the tag is still needed for answering search request
					entry->taglist.push_back(tag);
				}
				else if (!tag->m_name.Compare(TAG_SIZE)){
					entry->size = tag->GetInt();
					// NOTE: always add the 'size' tag, even if it's stored separately in 'size'. the tag is still needed for answering search request
					entry->taglist.push_back(tag);
				}
				else if (!tag->m_name.Compare(TAG_SOURCEPORT)){
					entry->tcpport = tag->GetInt();
					entry->taglist.push_back(tag);
				}
				else
				{
					//TODO: Filter tags
					entry->taglist.push_back(tag);
				}
				tags--;
			}
			if( !entry->source && (entry->fileName == "" || entry->size == 0 ))
			{
				delete entry;
				TRACE("Invalid entry\n");
			}
			else
			{
				// add sourceip for keyword publish packet
				if( !entry->source)
					entry->taglist.push_back(new CTagUInt32(TAG_SOURCEIP, entry->ip));
					
				indexed->IndexedAdd(file, target, entry);
			}
			count--;
		}	
//		CKademlia::debugMsg("Sent UDP OpCode KADEMLIA_PUBLISH_RES (%u)", ntohl(senderAddress->sin_addr.s_addr));
		byte response[18];
		CByteIO bio2(response, sizeof(response));
		bio2.writeByte(OP_KADEMLIAHEADER);
		bio2.writeByte(KADEMLIA_PUBLISH_RES);
		bio2.writeUInt128(file);
		sendPacket(response, sizeof(response), ntohl(senderAddress->sin_addr.s_addr), ntohs(senderAddress->sin_port)) ;
	} catch (...) {TRACE("Exception in Kademlia Publish Request\n");}
}

//KADEMLIA_PUBLISH_ACK
void CKademliaUDPListener::processPublishResponse (const byte *packetData, const uint32 lenPacket, const sockaddr_in *senderAddress)
{
	try
	{
		if (lenPacket != 16){
			ASSERT(0);
			return;
		}

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

		// Set contact to alive.
		routingZone->setAlive(ntohl(senderAddress->sin_addr.s_addr), ntohs(senderAddress->sin_port));

		CByteIO bio(packetData, lenPacket);
		CUInt128 file;
		bio.readUInt128(&file);
		CSearchManager::processPublishResult(file);
	} catch (...) {TRACE("Exception in Kademlia Publish Response\n");}
}
//KADEMLIA_FIREWALLED_REQ
void CKademliaUDPListener::processFirewalledRequest (const byte *packetData, const uint32 lenPacket, const sockaddr_in *senderAddress)
{
	try
	{
		if (lenPacket != 2 && lenPacket != 4){
			ASSERT(0);
			return;
		}

		CByteIO bio(packetData, lenPacket);
		uint16 tcpport = bio.readUInt16();
		uint16 udpport = ntohs(senderAddress->sin_port);
		uint32 ip = ntohl(senderAddress->sin_addr.s_addr);
		uint16 udpport2 = (lenPacket == 4 ? bio.readUInt16() : 0);

		if(lenPacket == 4){
			CContact* contact = new CContact();
			contact->setIPAddress(ip);
			contact->setTCPPort(tcpport);
			contact->setUDPPort(udpport);
			Kademlia::CKademlia::reportRequestTcp(contact);
		}

		// Send response
		byte response[6];
		CByteIO bio2(response, sizeof(response));
		bio2.writeByte(OP_KADEMLIAHEADER);
		bio2.writeByte(KADEMLIA_FIREWALLED_RES);
		bio2.writeUInt32(ip);
//		CKademlia::debugMsg("Sent UDP OpCode KADEMLIA_FIREWALLED_RES (%u)", ip);
		sendPacket(response, sizeof(response), ip, udpport);

		if(udpport2)
			sendPacket(response, sizeof(response), ip, udpport2);
	} catch (...) {TRACE("Exception in Kademlia Firewall Request\n");}
}

//KADEMLIA_FIREWALLED_RES
void CKademliaUDPListener::processFirewalledResponse (const byte *packetData, const uint32 lenPacket, const sockaddr_in *senderAddress)
{
	try
	{
		if (lenPacket != 4){
			ASSERT(0);
			return;
		}

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

		// Set contact to alive.
		routingZone->setAlive(ntohl(senderAddress->sin_addr.s_addr), ntohs(senderAddress->sin_port));

		CByteIO bio(packetData, lenPacket);
		uint32 ip = bio.readUInt32();
		CPrefs *prefs = CKademlia::getPrefs();
		ASSERT(prefs != NULL); 
		prefs->setIPAddress(ip);
		CString ipStr;
		CMiscUtils::ipAddressToString(ip, &ipStr);
	} catch (...) {TRACE("Exception in Kademlia Firewall Response\n");}
}

//KADEMLIA_FIREWALLED_ACK
void CKademliaUDPListener::processFirewalledResponse2 (const byte *packetData, const uint32 lenPacket, const sockaddr_in *senderAddress)
{
	try
	{
		if (lenPacket != 0){
			ASSERT(0);
			return;
		}

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

		// Set contact to alive.
		routingZone->setAlive(ntohl(senderAddress->sin_addr.s_addr), ntohs(senderAddress->sin_port));

		prefs->incFirewalled();
	} catch (...) {TRACE("Exception in Kademlia Firewall Response2\n");}
}

void CKademliaUDPListener::processPartialRequest (const byte *packetData, const uint32 lenPacket, const sockaddr_in *senderAddress)
{
	byte tth[24];

	try
	{
		if (lenPacket < 27){  // 27 = sizeof(tth) + sizeof(tcpPort) + sizeof(count)
			ASSERT(0);
			return;
		}

		CByteIO bio(packetData, lenPacket);
		uint16 tcpport = bio.readUInt16();

        bio.readArray(tth, sizeof(tth));
		uint8 cnt = bio.readUInt8();

		uint32 lenExpect = (uint32)(27 + cnt * sizeof(unsigned short) * 2);
		if(lenPacket < lenExpect){
			ASSERT(0);
			return;
		}

		const uint8* extension = NULL;
		
		// Check extension length, if illegal, clear it
		if(lenPacket > lenExpect){
			uint32* lenExtension = (uint32*)(packetData + lenExpect);
			if(lenPacket >= lenExpect + *lenExtension)
				extension = packetData + lenExpect;
		}
		
		uint32 ip = ntohl(senderAddress->sin_addr.s_addr);
		uint16 udpport = ntohs(senderAddress->sin_port);

		uint8 cnt2 = 0xFF;
		byte response[1500];	// TODO: buffer overrun

		// Callback to get partical info
		if(partialRequestHandler == NULL ||
		  !partialRequestHandler(ip, tcpport, udpport, tth, cnt, (uint16*)(packetData + 27), extension, &cnt2, (uint16*)(response + 29)))
			return; 

		if(cnt2 == 0){
			ASSERT(0);
			return;
		}

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

		// Send response
		CByteIO bio2(response, sizeof(response));
		bio2.writeByte(OP_KADEMLIAHEADER);
		bio2.writeByte(KADEMLIA_PARTIAL_RES);
		bio2.writeUInt16(prefs->getTCPPort());
		bio2.writeArray(tth, sizeof(tth));
		bio2.writeUInt8(cnt2);

		CKademlia::debugMsg("Sent UDP OpCode KADEMLIA_PARTIAL_RES (%u)", ip);
		sendPacket(response, 29 + sizeof(unsigned short) * cnt2 * 2, ip, udpport);

	} catch (...) {TRACE("Exception in Kademlia Partial Request\n");}
}

void CKademliaUDPListener::processPartialResponse (const byte *packetData, const uint32 lenPacket, const sockaddr_in *senderAddress)
{
	byte tth[24];

	try
	{
		if (lenPacket < 27){
			ASSERT(0);
			return;
		}

		CByteIO bio(packetData, lenPacket);
		uint16 tcpport = bio.readUInt16();

		if(tcpport == 0){
			ASSERT(0);			// TODO: This request is sent from passive user, ignore it now.
			return;
		}

		bio.readArray(tth, sizeof(tth));
		uint8 cnt = bio.readUInt8();

		if(lenPacket < (uint32)(27 + cnt * sizeof(unsigned short) * 2)){
			ASSERT(0);
			return;
		}

		uint32 ip = ntohl(senderAddress->sin_addr.s_addr);
		uint16 udpport = ntohs(senderAddress->sin_port);

		if(partialResponseHandler == NULL ||
		  !partialResponseHandler(ip, tcpport, udpport, tth, cnt, (uint16*)(packetData + 27)))
			return; 

	} catch (...) {TRACE("Exception in Kademlia Partial Response\n");}
}

void CKademliaUDPListener::processRevConnectRequest (const byte *packetData, const uint32 lenPacket, const sockaddr_in *senderAddress)
{
	try
	{
		if(revConnectRequestHandler == NULL){
			CKademlia::debugMsg("No Handler For UDP OpCode KADEMLIA_REVCONNECT_REQ");
		}

		if (lenPacket < 2){
			ASSERT(0);
			return;
		}

		CByteIO bio(packetData, lenPacket);
		uint16 tcpport = bio.readUInt16();

		uint32 ip = ntohl(senderAddress->sin_addr.s_addr);
		uint16 udpport = ntohs(senderAddress->sin_port);

		// Callback to handler
		revConnectRequestHandler(ip, tcpport, udpport, packetData + 2, lenPacket - 2);

	} catch (...) {TRACE("Exception in Kademlia RevConnect Request\n");}
}

⌨️ 快捷键说明

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