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

📄 kademliaudplistener.cpp

📁 电驴下载工具eMule0.47aVeryCD的源代码,可作分析测试也可用于P2P软件的开发研究.
💻 CPP
📖 第 1 页 / 共 5 页
字号:

// Used only for Kad1.0
void CKademliaUDPListener::Process_KADEMLIA_BOOTSTRAP_REQ (const byte *pbyPacketData, uint32 uLenPacket, uint32 uIP, uint16 uUDPPort)
{
	// Verify packet is expected size
	if (uLenPacket != 25)
	{
		CString strError;
		strError.Format(_T("***NOTE: Received wrong size (%u) packet in %hs"), uLenPacket, __FUNCTION__);
		throw strError;
	}

	// Add the sender to the list of contacts
	AddContact(pbyPacketData, uLenPacket, uIP, uUDPPort);

	// Get some contacts to return
	ContactList contacts;
	uint16 uNumContacts = 1 + (uint16)CKademlia::GetRoutingZone()->GetBootstrapContacts(&contacts, 20);

	// Create response packet
	//We only collect a max of 20 contacts here.. Max size is 527.
	//2 + 25(20) + 25
	CSafeMemFile fileIO(527);

	// Write packet info
	fileIO.WriteUInt16(uNumContacts);
	for (ContactList::const_iterator iContactList = contacts.begin(); iContactList != contacts.end(); ++iContactList)
	{
		CContact* pContact = *iContactList;
		fileIO.WriteUInt128(&pContact->GetClientID());
		fileIO.WriteUInt32(pContact->GetIPAddress());
		fileIO.WriteUInt16(pContact->GetUDPPort());
		fileIO.WriteUInt16(pContact->GetTCPPort());
		fileIO.WriteUInt8(pContact->GetType());
	}
	fileIO.WriteUInt128(&CKademlia::GetPrefs()->GetKadID());
	fileIO.WriteUInt32(CKademlia::GetPrefs()->GetIPAddress());
	fileIO.WriteUInt16(thePrefs.GetUDPPort());
	fileIO.WriteUInt16(thePrefs.GetPort());
	fileIO.WriteUInt8(0);

	// Send response
	if (thePrefs.GetDebugClientKadUDPLevel() > 0)
		DebugSend("KADEMLIA_BOOTSTRAP_RES", uIP, uUDPPort);

	SendPacket(&fileIO, KADEMLIA_BOOTSTRAP_RES, uIP, uUDPPort);
}

// Used only for Kad2.0
void CKademliaUDPListener::Process_KADEMLIA2_BOOTSTRAP_REQ (uint32 uIP, uint16 uUDPPort)
{
	// Get some contacts to return
	ContactList contacts;
	uint16 uNumContacts = (uint16)CKademlia::GetRoutingZone()->GetBootstrapContacts(&contacts, 20);

	// Create response packet
	//We only collect a max of 20 contacts here.. Max size is 527.
	//2 + 25(20) + 19
	CSafeMemFile fileIO(521);

	fileIO.WriteUInt128(&CKademlia::GetPrefs()->GetKadID());
	fileIO.WriteUInt16(thePrefs.GetPort());
	fileIO.WriteUInt8(KADEMLIA_VERSION);

	// Write packet info
	fileIO.WriteUInt16(uNumContacts);
	for (ContactList::const_iterator iContactList = contacts.begin(); iContactList != contacts.end(); ++iContactList)
	{
		CContact* pContact = *iContactList;
		fileIO.WriteUInt128(&pContact->GetClientID());
		fileIO.WriteUInt32(pContact->GetIPAddress());
		fileIO.WriteUInt16(pContact->GetUDPPort());
		fileIO.WriteUInt16(pContact->GetTCPPort());
		fileIO.WriteUInt8(pContact->GetVersion());
	}

	// Send response
	if (thePrefs.GetDebugClientKadUDPLevel() > 0)
		DebugSend("KADEMLIA2_BOOTSTRAP_RES", uIP, uUDPPort);

	SendPacket(&fileIO, KADEMLIA2_BOOTSTRAP_RES, uIP, uUDPPort);
}

// Used only for Kad1.0
void CKademliaUDPListener::Process_KADEMLIA_BOOTSTRAP_RES (const byte *pbyPacketData, uint32 uLenPacket)
{
	// Verify packet is expected size
	if (uLenPacket < 27)
	{
		CString strError;
		strError.Format(_T("***NOTE: Received wrong size (%u) packet in %hs"), uLenPacket, __FUNCTION__);
		throw strError;
	}

	// How many contacts were given
	CSafeMemFile fileIO( pbyPacketData, uLenPacket);
	uint16 uNumContacts = fileIO.ReadUInt16();

	// Verify packet is expected size
	if (uLenPacket != (UINT)(2 + 25*uNumContacts))
		return;

	// Add these contacts to the list.
	AddContacts(pbyPacketData+2, uLenPacket-2, uNumContacts);
}

// Used only for Kad2.0
void CKademliaUDPListener::Process_KADEMLIA2_BOOTSTRAP_RES (const byte *pbyPacketData, uint32 uLenPacket, uint32 uIP, uint16 uUDPPort)
{
	CRoutingZone *pRoutingZone = CKademlia::GetRoutingZone();

	// How many contacts were given
	CSafeMemFile fileIO( pbyPacketData, uLenPacket);
	CUInt128 uContactID;
	fileIO.ReadUInt128(&uContactID);
	uint16 uTCPPort = fileIO.ReadUInt16();
	uint8 uVersion = fileIO.ReadUInt8();
	pRoutingZone->Add(uContactID, uIP, uUDPPort, uTCPPort, uVersion);

	uint16 uNumContacts = fileIO.ReadUInt16();
	while(uNumContacts)
	{
		fileIO.ReadUInt128(&uContactID);
		uint32 uIP = fileIO.ReadUInt32();
		uint16 uUDPPort = fileIO.ReadUInt16();
		uint16 uTCPPort = fileIO.ReadUInt16();
		uint8 uVersion = fileIO.ReadUInt8();
		pRoutingZone->Add(uContactID, uIP, uUDPPort, uTCPPort, uVersion);
		uNumContacts--;
	}
}

// Used in Kad1.0 only.
void CKademliaUDPListener::Process_KADEMLIA_HELLO_REQ (const byte *pbyPacketData, uint32 uLenPacket, uint32 uIP, uint16 uUDPPort)
{
	// Verify packet is expected size
	if (uLenPacket != 25)
	{
		CString strError;
		strError.Format(_T("***NOTE: Received wrong size (%u) packet in %hs"), uLenPacket, __FUNCTION__);
		throw strError;
	}

	// Add the sender to the list of contacts
	AddContact(pbyPacketData, uLenPacket, uIP, uUDPPort);

	// Send response
	if (thePrefs.GetDebugClientKadUDPLevel() > 0)
		DebugSend("KADEMLIA_HELLO_RES", uIP, uUDPPort);
	SendMyDetails(KADEMLIA_HELLO_RES, uIP, uUDPPort);

	// Check if firewalled
	if(CKademlia::GetPrefs()->GetRecheckIP())
		FirewalledCheck(uIP, uUDPPort);
}

// Used in Kad2.0 only
void CKademliaUDPListener::Process_KADEMLIA2_HELLO_REQ (const byte *pbyPacketData, uint32 uLenPacket, uint32 uIP, uint16 uUDPPort)
{
	AddContact_KADEMLIA2(pbyPacketData, uLenPacket, uIP, uUDPPort);

	if (thePrefs.GetDebugClientKadUDPLevel() > 0)
		DebugSend("KADEMLIA2_HELLO_RES", uIP, uUDPPort);
	SendMyDetails_KADEMLIA2(KADEMLIA2_HELLO_RES, uIP, uUDPPort);

	// Check if firewalled
	if(CKademlia::GetPrefs()->GetRecheckIP())
		FirewalledCheck(uIP, uUDPPort);
}

// Used in Kad1.0 only
void CKademliaUDPListener::Process_KADEMLIA_HELLO_RES (const byte *pbyPacketData, uint32 uLenPacket, uint32 uIP, uint16 uUDPPort)
{
	// Verify packet is expected size
	if (uLenPacket != 25)
	{
		CString strError;
		strError.Format(_T("***NOTE: Received wrong size (%u) packet in %hs"), uLenPacket, __FUNCTION__);
		throw strError;
	}

	// Add or Update contact.
	AddContact(pbyPacketData, uLenPacket, uIP, uUDPPort);

	// Set contact to alive.
	CKademlia::GetRoutingZone()->SetAlive(uIP, uUDPPort);
}

// Used in Kad2.0 only
void CKademliaUDPListener::Process_KADEMLIA2_HELLO_RES (const byte *pbyPacketData, uint32 uLenPacket, uint32 uIP, uint16 uUDPPort)
{
	// Add or Update contact.
	AddContact_KADEMLIA2(pbyPacketData, uLenPacket, uIP, uUDPPort);

	// Set contact to alive.
	CKademlia::GetRoutingZone()->SetAlive(uIP, uUDPPort);
}

// Used in Kad1.0 only
void CKademliaUDPListener::Process_KADEMLIA_REQ (const byte *pbyPacketData, uint32 uLenPacket, uint32 uIP, uint16 uUDPPort)
{
	// Verify packet is expected size
	if (uLenPacket != 33)
	{
		CString strError;
		strError.Format(_T("***NOTE: Received wrong size (%u) packet in %hs"), uLenPacket, __FUNCTION__);
		throw strError;
	}

	//RecheckIP and firewall status
	if(CKademlia::GetPrefs()->GetRecheckIP())
	{
		FirewalledCheck(uIP, uUDPPort);
		if (thePrefs.GetDebugClientKadUDPLevel() > 0)
			DebugSend("KADEMLIA_HELLO_REQ", uIP, uUDPPort);
		SendMyDetails(KADEMLIA_HELLO_REQ, uIP, uUDPPort);
	}

	// Get target and type
	CSafeMemFile fileIO( pbyPacketData, uLenPacket);
	byte byType = fileIO.ReadUInt8();
	//		bool flag1 = (byType >> 6); //Reserved
	//		bool flag2 = (byType >> 7); //Reserved
	//		bool flag3 = (byType >> 8); //Reserved

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

	//This is the target node trying to be found.
	CUInt128 uTarget;
	fileIO.ReadUInt128(&uTarget);
	CUInt128 uDistance(CKademlia::GetPrefs()->GetKadID());
	uDistance.Xor(uTarget);

	//This makes sure we are not mistaken identify. Some client may have fresh installed and have a new hash.
	CUInt128 uCheck;
	fileIO.ReadUInt128(&uCheck);
	if(CKademlia::GetPrefs()->GetKadID() == uCheck)
	{
		// Get required number closest to target
		ContactMap results;
		CKademlia::GetRoutingZone()->GetClosestTo(2, uTarget, uDistance, (int)byType, &results);
		uint16 uCount = (uint16)results.size();

		// Write response
		// Max count is 32. size 817..
		// 16 + 1 + 25(32)
		CSafeMemFile fileIO2( 817 );
		fileIO2.WriteUInt128(&uTarget);
		fileIO2.WriteUInt8((byte)uCount);
		CUInt128 uID;
		for (ContactMap::const_iterator itContactMap = results.begin(); itContactMap != results.end(); ++itContactMap)
		{
			CContact* pContact = itContactMap->second;
			pContact->GetClientID(&uID);
			fileIO2.WriteUInt128(&uID);
			fileIO2.WriteUInt32(pContact->GetIPAddress());
			fileIO2.WriteUInt16(pContact->GetUDPPort());
			fileIO2.WriteUInt16(pContact->GetTCPPort());
			fileIO2.WriteUInt8(pContact->GetType());
		}

		if (thePrefs.GetDebugClientKadUDPLevel() > 0)
			DebugSendF("KADEMLIA_RES", uIP, uUDPPort, _T("Count=%u"), uCount);

		SendPacket(&fileIO2, KADEMLIA_RES, uIP, uUDPPort);
	}
}

// Used in Kad2.0 only
void CKademliaUDPListener::Process_KADEMLIA2_REQ (const byte *pbyPacketData, uint32 uLenPacket, uint32 uIP, uint16 uUDPPort)
{
	// Get target and type
	CSafeMemFile fileIO( pbyPacketData, uLenPacket);
	byte byType = fileIO.ReadUInt8();
	byType = byType & 0x1F;
	if( byType == 0 )
	{
		CString strError;
		strError.Format(_T("***NOTE: Received wrong type (0x%02x) in %hs"), byType, __FUNCTION__);
		throw strError;
	}

	//This is the target node trying to be found.
	CUInt128 uTarget;
	fileIO.ReadUInt128(&uTarget);
	//Convert Target to Distance as this is how we store contacts.
	CUInt128 uDistance(CKademlia::GetPrefs()->GetKadID());
	uDistance.Xor(uTarget);

	//This makes sure we are not mistaken identify. Some client may have fresh installed and have a new KadID.
	CUInt128 uCheck;
	fileIO.ReadUInt128(&uCheck);
	if(CKademlia::GetPrefs()->GetKadID() == uCheck)
	{
		// Get required number closest to target
		ContactMap results;
		CKademlia::GetRoutingZone()->GetClosestTo(2, uTarget, uDistance, (uint32)byType, &results);
		uint8 uCount = (uint8)results.size();

		// Write response
		// Max count is 32. size 817..
		// 16 + 1 + 25(32)
		CSafeMemFile fileIO2( 817 );
		fileIO2.WriteUInt128(&uTarget);
		fileIO2.WriteUInt8(uCount);
		CUInt128 uID;
		for (ContactMap::const_iterator itContactMap = results.begin(); itContactMap != results.end(); ++itContactMap)
		{
			CContact* pContact = itContactMap->second;
			pContact->GetClientID(&uID);
			fileIO2.WriteUInt128(&uID);
			fileIO2.WriteUInt32(pContact->GetIPAddress());
			fileIO2.WriteUInt16(pContact->GetUDPPort());
			fileIO2.WriteUInt16(pContact->GetTCPPort());
			fileIO2.WriteUInt8(1); //<- Kad Version inserted to allow backward compatability.
		}

		if (thePrefs.GetDebugClientKadUDPLevel() > 0)
			DebugSendF("KADEMLIA2_RES", uIP, uUDPPort, _T("Count=%u"), uCount);

		SendPacket(&fileIO2, KADEMLIA2_RES, uIP, uUDPPort);
	}
}

// Used in Kad1.0 only
void CKademliaUDPListener::Process_KADEMLIA_RES (const byte *pbyPacketData, uint32 uLenPacket, uint32 uIP, uint16 uUDPPort)
{
	// Verify packet is expected size
	if (uLenPacket < 17)
	{
		CString strError;
		strError.Format(_T("***NOTE: Received wrong size (%u) packet in %hs"), uLenPacket, __FUNCTION__);
		throw strError;
	}

	//Used Pointers
	CRoutingZone *pRoutingZone = CKademlia::GetRoutingZone();

	if(CKademlia::GetPrefs()->GetRecheckIP())
	{
		FirewalledCheck(uIP, uUDPPort);
		if (thePrefs.GetDebugClientKadUDPLevel() > 0)
			DebugSend("KADEMLIA_HELLO_REQ", uIP, uUDPPort);
		SendMyDetails(KADEMLIA_HELLO_REQ, uIP, uUDPPort);
	}

	// What search does this relate to
	CSafeMemFile fileIO( pbyPacketData, uLenPacket);
	CUInt128 uTarget;
	fileIO.ReadUInt128(&uTarget);
	uint16 uNumContacts = fileIO.ReadUInt8();

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

	ContactList *pResults = new ContactList;
	CUInt128 uIDResult;
	try
	{
		for (uint16 iIndex=0; iIndex<uNumContacts; iIndex++)
		{
			fileIO.ReadUInt128(&uIDResult);
			uint32 uIPResult = fileIO.ReadUInt32();
			uint16 uUDPPortResult = fileIO.ReadUInt16();
			uint16 uTCPPortResult = fileIO.ReadUInt16();
			fileIO.ReadUInt8();
			if(::IsGoodIPPort(ntohl(uIPResult),uUDPPortResult))
			{
				pRoutingZone->Add(uIDResult, uIPResult, uUDPPortResult, uTCPPortResult, 0);
				pResults->push_back(new CContact(uIDResult, uIPResult, uUDPPortResult, uTCPPortResult, uTarget, 0));
			}
		}
	}
	catch(...)
	{
		delete pResults;
		throw;
	}
	CSearchManager::ProcessResponse(uTarget, uIP, uUDPPort, pResults);
}

// Used in Kad2.0 only
void CKademliaUDPListener::Process_KADEMLIA2_RES (const byte *pbyPacketData, uint32 uLenPacket, uint32 uIP, uint16 uUDPPort)
{
	//Used Pointers
	CRoutingZone *pRoutingZone = CKademlia::GetRoutingZone();

	if(CKademlia::GetPrefs()->GetRecheckIP())
	{
		FirewalledCheck(uIP, uUDPPort);
		if (thePrefs.GetDebugClientKadUDPLevel() > 0)
			DebugSend("KADEMLIA2_HELLO_REQ", uIP, uUDPPort);
		SendMyDetails_KADEMLIA2(KADEMLIA2_HELLO_REQ, uIP, uUDPPort);
	}

	// What search does this relate to
	CSafeMemFile fileIO( pbyPacketData, uLenPacket);
	CUInt128 uTarget;
	fileIO.ReadUInt128(&uTarget);
	uint8 uNumContacts = fileIO.ReadUInt8();

	// Verify packet is expected size
	if (uLenPacket != (UINT)(16+1 + (16+4+2+2+1)*uNumContacts))
	{
		CString strError;
		strError.Format(_T("***NOTE: Received wrong size (%u) packet in %hs"), uLenPacket, __FUNCTION__);
		throw strError;

⌨️ 快捷键说明

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