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

📄 kademliaudplistener.cpp

📁 Kademlia---第第3代P2P原代码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
//KADEMLIA_HELLO_REQ
void CKademliaUDPListener::processHelloRequest (const byte *packetData, const uint32 lenPacket, const sockaddr_in *senderAddress)
{
	try
	{
		if (lenPacket != 25){
			ASSERT(0);
			return;
		}

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

		// Add the sender to the list of contacts
		addContact(packetData, lenPacket, ntohl(senderAddress->sin_addr.s_addr), ntohs(senderAddress->sin_port));

		// Send response
//		CKademlia::debugMsg("Sent UDP OpCode KADEMLIA_HELLO_RES (%u)", ntohl(senderAddress->sin_addr.s_addr));
		sendMyDetails(KADEMLIA_HELLO_RES,ntohl(senderAddress->sin_addr.s_addr), ntohs(senderAddress->sin_port));
		if(prefs->getRecheckIP())
		{
			// Check if firewalled
			firewalledCheck(ntohl(senderAddress->sin_addr.s_addr), ntohs(senderAddress->sin_port));
		}	
	} catch (...) {TRACE("Exception in Kademlia Hello Requests\n");}
}

//KADEMLIA_HELLO_RES
void CKademliaUDPListener::processHelloResponse (const byte *packetData, const uint32 lenPacket, const sockaddr_in *senderAddress)
{
	try
	{
		if (lenPacket != 25){
			ASSERT(0);
			return;
		}
	
		//Used Pointers
		CRoutingZone *routingZone = CKademlia::getRoutingZone();
		ASSERT(routingZone != NULL); 
		CPrefs *prefs = CKademlia::getPrefs();
		ASSERT(prefs != NULL); 
	
		// Add or Update contact.
		addContact(packetData, lenPacket, ntohl(senderAddress->sin_addr.s_addr), ntohs(senderAddress->sin_port));

		// Set contact to alive.
		routingZone->setAlive(ntohl(senderAddress->sin_addr.s_addr), ntohs(senderAddress->sin_port));
	
	} catch (...) {TRACE("Exception in Kademlia Hello Response\n");}
}
//KADEMLIA_REQ
void CKademliaUDPListener::processKademliaRequest (const byte *packetData, const uint32 lenPacket, const sockaddr_in *senderAddress)
{
	try
	{
		// Verify packet is expected size
		if (lenPacket != 33){
			ASSERT(0);
			return;
		}

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

		if(prefs->getRecheckIP())
		{
			firewalledCheck(ntohl(senderAddress->sin_addr.s_addr), ntohs(senderAddress->sin_port));
			sendMyDetails(KADEMLIA_HELLO_REQ, ntohl(senderAddress->sin_addr.s_addr), ntohs(senderAddress->sin_port));
		}

		// Get target and type
		CByteIO bio(packetData, lenPacket);
		byte type = bio.readByte();
		CUInt128 target;
		bio.readUInt128(&target);
		CUInt128 check;
		bio.readUInt128(&check);

		if( prefs->getClientID().compareTo(check))
			return;

		// Get required number closest to target
		ContactMap results;
		CUInt128 distance(prefs->getClientID());
		distance.xor(target);
		routingZone->getClosestTo(0, distance, (int)type, &results);
		uint16 count = (uint16)results.size();

		// Write response
		uint32 lenResponse = 1+1+16+1 + (16+4+2+2+1)*count;
		byte response[1024];
		ASSERT(lenResponse <= sizeof(response));
		CByteIO bio2(response, lenResponse);
		bio2.writeByte(OP_KADEMLIAHEADER);
		bio2.writeByte(KADEMLIA_RES);
		bio2.writeUInt128(target);
		bio2.writeByte((byte)count);
		CContact *c;
		CUInt128 id;
		ContactMap::const_iterator it;
		for (it = results.begin(); it != results.end(); it++)
		{
			c = it->second;
			c->getClientID(&id);
			bio2.writeUInt128(id);
			bio2.writeUInt32(c->getIPAddress());
			bio2.writeUInt16(c->getUDPPort());
			bio2.writeUInt16(c->getTCPPort());
			bio2.writeByte(c->getType());
		}
//		CKademlia::debugMsg("Sent UDP OpCode KADEMLIA_RES (%u)", ntohl(senderAddress->sin_addr.s_addr));
		sendPacket(response, lenResponse, ntohl(senderAddress->sin_addr.s_addr), ntohs(senderAddress->sin_port));

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

//KADEMLIA_RES
void CKademliaUDPListener::processKademliaResponse (const byte *packetData, const uint32 lenPacket, const sockaddr_in *senderAddress)
{
	try
	{
		// Verify packet is expected size
		if (lenPacket < 17){
			ASSERT(0);
			return;
		}

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

		if(prefs->getRecheckIP())
		{
			firewalledCheck(ntohl(senderAddress->sin_addr.s_addr), ntohs(senderAddress->sin_port));
			sendMyDetails(KADEMLIA_HELLO_REQ, 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);
		uint16 numContacts = bio.readByte();

		// Verify packet is expected size
		if (lenPacket != 16+1 + (16+4+2+2+1)*numContacts){
			ASSERT(0);
			return;
		}

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

		CUInt128 id;
		ContactList *results = new ContactList;
		for (uint16 i=0; i<numContacts; i++)
		{
			bio.readUInt128(&id);
			uint32 ip = bio.readUInt32(); // Not LE
			uint16 port = bio.readUInt16();
			uint16 tport = bio.readUInt16();
			byte type = bio.readByte();
			if(::IsGoodIPPort(ntohl(ip),port))
			{
				routingZone->add(id, ip, port, tport, type);
				results->push_back(new CContact(id, ip, port, tport, type, target));
			}
		}
		CSearchManager::processResponse(target, 
										ntohl(senderAddress->sin_addr.s_addr), ntohs(senderAddress->sin_port), 
										results);
	} catch (...) {TRACE("Exception in Kademlia Response\n");}
}

void Free(SSearchTerm* pSearchTerms)
{
	if (pSearchTerms->left)
		Free(pSearchTerms->left);
	if (pSearchTerms->right)
		Free(pSearchTerms->right);
	delete pSearchTerms;
}

SSearchTerm* CreateSearchExpressionTree(CByteIO& bio, int iLevel)
{
	// the max. depth has to match our own limit for creating the search expression 
	// (see also 'ParsedSearchExpression' and 'GetSearchPacket')
	if (iLevel >= 16){
		TRACE("*** Search expression tree exceeds depth limit!\n");
		return NULL;
	}
	iLevel++;

	uint8 op = bio.readByte();
	if (op == 0x00){
		uint8 boolop = bio.readByte();
		if (boolop == 0x00){ // AND
			SSearchTerm* pSearchTerm = new SSearchTerm;
			pSearchTerm->type = SSearchTerm::AND;
			TRACE(" AND");
			if ((pSearchTerm->left = CreateSearchExpressionTree(bio, iLevel)) == NULL){
				// ASSERT(0);
				delete pSearchTerm;
				return NULL;
			}
			if ((pSearchTerm->right = CreateSearchExpressionTree(bio, iLevel)) == NULL){
				// ASSERT(0);
				Free(pSearchTerm->left);
				delete pSearchTerm;
				return NULL;
			}
			return pSearchTerm;
		}
		else if (boolop == 0x01){ // OR
			SSearchTerm* pSearchTerm = new SSearchTerm;
			pSearchTerm->type = SSearchTerm::OR;
			TRACE(" OR");
			if ((pSearchTerm->left = CreateSearchExpressionTree(bio, iLevel)) == NULL){
				ASSERT(0);
				delete pSearchTerm;
				return NULL;
			}
			if ((pSearchTerm->right = CreateSearchExpressionTree(bio, iLevel)) == NULL){
				ASSERT(0);
				Free(pSearchTerm->left);
				delete pSearchTerm;
				return NULL;
			}
			return pSearchTerm;
		}
		else if (boolop == 0x02){ // NAND
			SSearchTerm* pSearchTerm = new SSearchTerm;
			pSearchTerm->type = SSearchTerm::NAND;
			TRACE(" NAND");
			if ((pSearchTerm->left = CreateSearchExpressionTree(bio, iLevel)) == NULL){
				ASSERT(0);
				delete pSearchTerm;
				return NULL;
			}
			if ((pSearchTerm->right = CreateSearchExpressionTree(bio, iLevel)) == NULL){
				ASSERT(0);
				Free(pSearchTerm->left);
				delete pSearchTerm;
				return NULL;
			}
			return pSearchTerm;
		}
		else{
			TRACE("*** Unknown boolean search operator 0x%02x\n", boolop);
			return NULL;
		}
	}
	else if (op == 0x01){ // String
		SSearchTerm* pSearchTerm = new SSearchTerm;
		pSearchTerm->type = SSearchTerm::String;
		uint16 len = bio.readUInt16();
		pSearchTerm->str = new CString;
		bio.readArray(pSearchTerm->str->GetBuffer(len), len);
		pSearchTerm->str->ReleaseBuffer(len);
		TRACE(" \"%s\"", *(pSearchTerm->str));
		return pSearchTerm;
	}
	else if (op == 0x02){ // Meta tag
		SSearchTerm* pSearchTerm = new SSearchTerm;
		pSearchTerm->type = SSearchTerm::MetaTag;

		// read tag value
		CString strValue;
		uint16 lenValue = bio.readUInt16();
		bio.readArray(strValue.GetBuffer(lenValue), lenValue);
		strValue.ReleaseBuffer(lenValue);

		// read tag name
		CString strTagName;
		uint16 lenTagName = bio.readUInt16();
		bio.readArray(strTagName.GetBuffer(lenTagName), lenTagName);
		strTagName.ReleaseBuffer(lenTagName);

		pSearchTerm->tag = new Kademlia::CTagStr(strTagName, strValue);
		if (lenTagName == 1)
			TRACE(" Tag%02x=\"%s\"", strTagName[0], strValue);
		else
			TRACE(" Tag\"%s\"=\"%s\"", strTagName, strValue);
		return pSearchTerm;
	}
	else if (op == 0x03){ // Min/Max
		SSearchTerm* pSearchTerm = new SSearchTerm;

		// read tag value
		uint32 uValue = bio.readUInt32();

		// read min/max operator
		uint8 mmop = bio.readByte();
		pSearchTerm->type = (mmop == 0x01) ? SSearchTerm::Min : SSearchTerm::Max;

		// read tag name
		CString strTagName;
		uint16 lenTagName = bio.readUInt16();
		bio.readArray(strTagName.GetBuffer(lenTagName), lenTagName);
		strTagName.ReleaseBuffer(lenTagName);

		pSearchTerm->tag = new Kademlia::CTagUInt32(strTagName, uValue);
		if (lenTagName == 1)
			TRACE(" %s(Tag%02x)=%u", pSearchTerm->type == SSearchTerm::Min ? "Min" : "Max", strTagName[0], uValue);
		else
			TRACE(" %s(Tag\"%s\")=%u", pSearchTerm->type == SSearchTerm::Min ? "Min" : "Max", strTagName, uValue);
		return pSearchTerm;
	}
	else{
		TRACE("*** Unknown search op=0x%02x\n", op);
		return NULL;
	}
}

//KADEMLIA_SEARCH_REQ
void CKademliaUDPListener::processSearchRequest (const byte *packetData, const uint32 lenPacket, const sockaddr_in *senderAddress)
{
	try
	{
		if (lenPacket < 17){
			ASSERT(0);
			return;
		}

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

		CByteIO bio(packetData, lenPacket);
		CUInt128 target;
		bio.readUInt128(&target);
		uint8 restrictive = bio.readByte();

		if(lenPacket == 17 ){
			if(restrictive)
			{
				//Source request
				indexed->SendValidResult(target, NULL, senderAddress, true );
			}
			else
			{
				//Single keyword request
				indexed->SendValidResult(target, NULL, senderAddress, false );
			}
		}
		else if(lenPacket > 17){

			SSearchTerm* pSearchTerms = NULL;
			if (restrictive){
				pSearchTerms = CreateSearchExpressionTree(bio, 0);
			}
			//Keyword request with added options.
			indexed->SendValidResult(target, pSearchTerms, senderAddress, false ); 
			Free(pSearchTerms);
		}
	} catch (...) {TRACE("Exception in Kademlia Search Request\n");}
}

//KADEMLIA_SEARCH_RES
void CKademliaUDPListener::processSearchResponse (const byte *packetData, const uint32 lenPacket, const sockaddr_in *senderAddress)
{
	try
	{
		// Verify packet is expected size
		if (lenPacket < 37){
			ASSERT(0);
			return;
		}

		//Used Pointers

⌨️ 快捷键说明

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