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

📄 kademliaudplistener.cpp

📁 一个关于电驴的源码,大家有需要可以下载
💻 CPP
📖 第 1 页 / 共 3 页
字号:
	if (lenPacket != (2 + 25*numContacts))
		return;

	// Add these contacts to the list.
	addContacts(packetData+2, lenPacket-2, numContacts);
	// Send sender to alive.
	routingZone->setAlive(ip, port);
}

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

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

	// Add the sender to the list of contacts
	addContact(packetData, lenPacket, ip, port);

	// Send response
	if (thePrefs.GetDebugClientKadUDPLevel() > 0)
		DebugSend("KadHelloRes", ip, port);
	sendMyDetails(KADEMLIA_HELLO_RES, ip, port);

	// Check if firewalled
	if(prefs->getRecheckIP())
	{
		firewalledCheck(ip, port);
	}
}

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

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

	// Add or Update contact.
	addContact(packetData, lenPacket, ip, port);

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

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

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

	//RecheckIP and firewall status
	if(prefs->getRecheckIP())
	{
		firewalledCheck(ip, port);
		if (thePrefs.GetDebugClientKadUDPLevel() > 0)
			DebugSend("KadHelloReq", ip, port);
		sendMyDetails(KADEMLIA_HELLO_REQ, ip, port);
	}

	// Get target and type
	CSafeMemFile bio( packetData, lenPacket);
	byte type = bio.ReadUInt8();
//		bool flag1 = (type >> 6); //Reserved
//		bool flag2 = (type >> 7); //Reserved
//		bool flag3 = (type >> 8); //Reserved

	type = type & 0x1F;
	if( type == 0 )
	{
		CString strError;
		strError.Format("***NOTE: Received wrong type (0x%02x) in %s", type, __FUNCTION__);
		throw strError;
	}

	//This is the target node trying to be found.
	CUInt128 target;
	bio.ReadUInt128(&target);
	CUInt128 distance(prefs->getClientID());
	distance.xor(target);

	//This makes sure we are not mistaken identify. Some client may have fresh installed and have a new hash.
	CUInt128 check;
	bio.ReadUInt128(&check);
	if( prefs->getClientID().compareTo(check))
		return;

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

	// Write response
	// Max count is 32. size 817.. 
	// 16 + 1 + 25(32)
	CSafeMemFile bio2( 817 );
	bio2.WriteUInt128(&target);
	bio2.WriteUInt8((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.WriteUInt8(c->getType());
	}

	if (thePrefs.GetDebugClientKadUDPLevel() > 0)
		DebugSendF("KadRes", ip, port, "Count=%u", count);

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

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

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

	if(prefs->getRecheckIP())
	{
		firewalledCheck(ip, port);
		if (thePrefs.GetDebugClientKadUDPLevel() > 0)
			DebugSend("KadHelloReq", ip, port);
		sendMyDetails(KADEMLIA_HELLO_REQ, ip, port);
	}

	// What search does this relate to
	CSafeMemFile bio( packetData, lenPacket);
	CUInt128 target;
	bio.ReadUInt128(&target);
	uint16 numContacts = bio.ReadUInt8();

	// Verify packet is expected size
	if (lenPacket != 16+1 + (16+4+2+2+1)*numContacts){
		CString strError;
		strError.Format("***NOTE: Received wrong size (%u) packet in %s", lenPacket, __FUNCTION__);
		throw strError;
	}

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

	CUInt128 id;
	ContactList *results = new ContactList;
	try
	{
		for (uint16 i=0; i<numContacts; i++)
		{
			bio.ReadUInt128(&id);
			uint32 ip = bio.ReadUInt32();
			uint16 port = bio.ReadUInt16();
			uint16 tport = bio.ReadUInt16();
			byte type = bio.ReadUInt8();
			if(::IsGoodIPPort(ntohl(ip),port))
			{
				routingZone->add(id, ip, port, tport, type);
				results->push_back(new CContact(id, ip, port, tport, type, target));
			}
		}
	}
	catch(...)
	{
		delete results;
		throw;
	}
	CSearchManager::processResponse(target, ip, port, results);
}

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

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

	uint8 op = bio.ReadUInt8();
	if (op == 0x00)
	{
		uint8 boolop = bio.ReadUInt8();
		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{
			CKademlia::debugMsg("*** Unknown boolean search operator 0x%02x (CreateSearchExpressionTree)", boolop);
			return NULL;
		}
	}
	else if (op == 0x01) // String
	{
		uint16 len = bio.ReadUInt16();
		CString str;
		bio.Read(str.GetBuffer(len), len);
		str.ReleaseBuffer(len);

		SSearchTerm* pSearchTerm = new SSearchTerm;
		pSearchTerm->type = SSearchTerm::String;
		pSearchTerm->astr = new CStringArray;

		str.MakeLower(); // make lowercase, the search code expects lower case strings!
		TRACE(" \"%s\"", str);

		// pre-tokenize the string term
		int iPosTok = 0;
		CString strTok(str.Tokenize(" ()[]{}<>,._-!?", iPosTok));
		while (!strTok.IsEmpty())
		{
			pSearchTerm->astr->Add(strTok);
			strTok = str.Tokenize(" ()[]{}<>,._-!?", iPosTok);
		}

		return pSearchTerm;
	}
	else if (op == 0x02) // Meta tag
	{
		// read tag value
		CString strValue;
		uint16 lenValue = bio.ReadUInt16();
		bio.Read(strValue.GetBuffer(lenValue), lenValue);
		strValue.ReleaseBuffer(lenValue);
		strValue.MakeLower(); // make lowercase, the search code expects lower case strings!

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

		SSearchTerm* pSearchTerm = new SSearchTerm;
		pSearchTerm->type = SSearchTerm::MetaTag;
		pSearchTerm->tag = new Kademlia::CTagStr(strTagName, strValue);
		if (lenTagName == 1)
			TRACE(" Tag%02x=\"%s\"", strTagName[0], strValue);
		else
			TRACE(" \"%s\"=\"%s\"", strTagName, strValue);
		return pSearchTerm;
	}
	else if (op == 0x03) // Min/Max
	{
		static const struct {
			SSearchTerm::ESearchTermType eSearchTermOp;
			LPCTSTR pszOp;
		} _aOps[] =
		{
			{ SSearchTerm::OpEqual,			"="		}, // mmop=0x00
			{ SSearchTerm::OpGreaterEqual,	">="	}, // mmop=0x01
			{ SSearchTerm::OpLessEqual,		"<="	}, // mmop=0x02
			{ SSearchTerm::OpGreater,		">"		}, // mmop=0x03
			{ SSearchTerm::OpLess,			"<"		}, // mmop=0x04
			{ SSearchTerm::OpNotEqual,		"!="	}  // mmop=0x05
		};

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

		// read integer operator
		uint8 mmop = bio.ReadUInt8();
		if (mmop >= ARRSIZE(_aOps)){
			CKademlia::debugMsg("*** Unknown integer search op=0x%02x (CreateSearchExpressionTree)", mmop);
			return NULL;
		}

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

		SSearchTerm* pSearchTerm = new SSearchTerm;
		pSearchTerm->type = _aOps[mmop].eSearchTermOp;
		pSearchTerm->tag = new Kademlia::CTagUInt32(strTagName, uValue);

		if (lenTagName == 1)
			TRACE(" Tag%02x%s%u", strTagName[0], _aOps[mmop].pszOp, uValue);
		else
			TRACE(" \"%s\"%s%u", strTagName, _aOps[mmop].pszOp, uValue);

		return pSearchTerm;
	}
	else{
		CKademlia::debugMsg("*** Unknown search op=0x%02x (CreateSearchExpressionTree)", op);
		return NULL;

⌨️ 快捷键说明

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