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

📄 kademliaudplistener.cpp

📁 电驴下载工具eMule0.47aVeryCD的源代码,可作分析测试也可用于P2P软件的开发研究.
💻 CPP
📖 第 1 页 / 共 5 页
字号:
/*
Copyright (C)2003 Barry Dunne (http://www.emule-project.net)
 
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
 
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.
 
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

// Note To Mods //
/*
Please do not change anything here and release it..
There is going to be a new forum created just for the Kademlia side of the client..
If you feel there is an error or a way to improve something, please
post it in the forum first and let us look at it.. If it is a real improvement,
it will be added to the offical client.. Changing something without knowing
what all it does can cause great harm to the network if released in mass form..
Any mod that changes anything within the Kademlia side will not be allowed to advertise
there client on the eMule forum..
*/

#include "stdafx.h"
#include "./KademliaUDPListener.h"
#include "../kademlia/Prefs.h"
#include "../kademlia/Kademlia.h"
#include "../kademlia/SearchManager.h"
#include "../kademlia/Indexed.h"
#include "../kademlia/Defines.h"
#include "../kademlia/Entry.h"
#include "../routing/RoutingZone.h"
#include "../io/ByteIO.h"
#include "../../emule.h"
#include "../../ClientUDPSocket.h"
#include "../../Packets.h"
#include "../../emuledlg.h"
#include "../../KadContactListCtrl.h"
#include "../../kademliawnd.h"
#include "../../clientlist.h"
#include "../../Statistics.h"
#include "../../updownclient.h"
#include "../../listensocket.h"
#include "../../Log.h"
#include "../../opcodes.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

extern LPCSTR _aszInvKadKeywordCharsA;
extern LPCWSTR _awszInvKadKeywordChars;

using namespace Kademlia;

// Used by Kad1.0 and Kad 2.0
void CKademliaUDPListener::Bootstrap(LPCTSTR szHost, uint16 uUDPPort)
{
	USES_CONVERSION;
	uint32 uRetVal = 0;
	if (_istalpha((_TUCHAR)szHost[0]))
	{
		hostent *php = gethostbyname(T2CA(szHost));
		if (php == NULL)
			return;
		memcpy (&uRetVal, php->h_addr, sizeof(uRetVal));
	}
	else
		uRetVal = inet_addr(T2CA(szHost));
	Bootstrap(ntohl(uRetVal), uUDPPort);
}

// Used by Kad1.0 and Kad 2.0
void CKademliaUDPListener::Bootstrap(uint32 uIP, uint16 uUDPPort)
{
	/*if(bKad2) //JOHNTODO - Need Toggle between Kad1.0/Kad2.0
	{
		if (thePrefs.GetDebugClientKadUDPLevel() > 0)
			DebugSend("KADEMLIA2_BOOTSTRAP_REQ", uIP, uUDPPort);
		CSafeMemFile fileIO(0);
		SendPacket(&fileIO, KADEMLIA2_BOOTSTRAP_REQ, uIP, uUDPPort);
	}
	else*/
	{
		if (thePrefs.GetDebugClientKadUDPLevel() > 0)
			DebugSend("KADEMLIA_BOOTSTRAP_REQ", uIP, uUDPPort);
		SendMyDetails(KADEMLIA_BOOTSTRAP_REQ, uIP, uUDPPort);
	}
}

// KAD1.0 only..
void CKademliaUDPListener::SendMyDetails(byte byOpcode, uint32 uIP, uint16 uUDPPort)
{
	CSafeMemFile fileIO(25);
	fileIO.WriteUInt128(&CKademlia::GetPrefs()->GetKadID());
	fileIO.WriteUInt32(CKademlia::GetPrefs()->GetIPAddress());
	fileIO.WriteUInt16(thePrefs.GetUDPPort());
	fileIO.WriteUInt16(thePrefs.GetPort());
	fileIO.WriteUInt8(0);
	SendPacket(&fileIO, byOpcode, uIP, uUDPPort);
}

// Kad2.0 only
void CKademliaUDPListener::SendMyDetails_KADEMLIA2(byte byOpcode, uint32 uIP, uint16 uUDPPort)
{
	byte byPacket[1024];
	CByteIO byteIOResponse(byPacket, sizeof(byPacket));
	byteIOResponse.WriteByte(OP_KADEMLIAHEADER);
	byteIOResponse.WriteByte(byOpcode);
	byteIOResponse.WriteUInt128(CKademlia::GetPrefs()->GetKadID());
	byteIOResponse.WriteUInt16(thePrefs.GetPort());
	byteIOResponse.WriteUInt8(KADEMLIA_VERSION);
	// Tag Count.
	byteIOResponse.WriteUInt8(2);
	byteIOResponse.WriteTag(&CKadTagUInt(TAG_USER_COUNT, CKademlia::GetPrefs()->GetKademliaUsers()));
	byteIOResponse.WriteTag(&CKadTagUInt(TAG_FILE_COUNT, CKademlia::GetPrefs()->GetKademliaFiles()));
	uint32 uLen = sizeof(byPacket) - byteIOResponse.GetAvailable();
	SendPacket(byPacket, uLen,  uIP, uUDPPort);
}

// Kad1.0 & Kad2.0 currently.
void CKademliaUDPListener::FirewalledCheck(uint32 uIP, uint16 uUDPPort)
{
	CSafeMemFile fileIO(2);
	fileIO.WriteUInt16(thePrefs.GetPort());
	if (thePrefs.GetDebugClientKadUDPLevel() > 0)
		DebugSend("KADEMLIA_FIREWALLED_REQ", uIP, uUDPPort);
	SendPacket(&fileIO, KADEMLIA_FIREWALLED_REQ, uIP, uUDPPort);
}

// JOHNTODO - Currently only used for Firewalled Ack.. Probably best to remove this method!
void CKademliaUDPListener::SendNullPacket(byte byOpcode,uint32 uIP, uint16 uUDPPort)
{
	CSafeMemFile fileIO(0);
	SendPacket(&fileIO, byOpcode, uIP, uUDPPort);
}

// JOHNTODO - Need to switch between Kad1.0 and Kad2.0.
void CKademliaUDPListener::SendPublishSourcePacket(uint32 uIP, uint16 uUDPPort, const CUInt128 &uTargetID, const CUInt128 &uContactID, const TagList& tags)
{
	//We need to get the tag lists working with CSafeMemFiles..
	byte byPacket[1024];
	CByteIO byteIO(byPacket, sizeof(byPacket));
	byteIO.WriteByte(OP_KADEMLIAHEADER);
	/*if(bKad2)
	{
		byteIO.WriteByte(KADEMLIA2_PUBLISH_SOURCE_REQ);
		byteIO.WriteUInt128(uTargetID);
		//We only use this for publishing sources now.. So we always send one here..
		byteIO.WriteUInt128(uContactID);
		byteIO.WriteTagList(tags);
		if (thePrefs.GetDebugClientKadUDPLevel() > 0)
		{
			DebugSend("KADEMLIA2_PUBLISH_SOURCE_REQ", uIP, uUDPPort);
		}
	}
	else*/
	{
		byteIO.WriteByte(KADEMLIA_PUBLISH_REQ);
		byteIO.WriteUInt128(uTargetID);
		//We only use this for publishing sources now.. So we always send one here..
		byteIO.WriteUInt16(1);
		byteIO.WriteUInt128(uContactID);
		byteIO.WriteTagList(tags);
		if (thePrefs.GetDebugClientKadUDPLevel() > 0)
		{
			DebugSend("KADEMLIA_PUBLISH_REQ", uIP, uUDPPort);
		}
	}
	uint32 uLen = sizeof(byPacket) - byteIO.GetAvailable();
	SendPacket(byPacket, uLen,  uIP, uUDPPort);
}

void CKademliaUDPListener::ProcessPacket(const byte* pbyData, uint32 uLenData, uint32 uIP, uint16 uUDPPort)
{
	//Update connection state only when it changes.
	bool bCurCon = CKademlia::GetPrefs()->HasHadContact();
	CKademlia::GetPrefs()->SetLastContact();
	if( bCurCon != CKademlia::GetPrefs()->HasHadContact())
		theApp.emuledlg->ShowConnectionState();

	byte byOpcode = pbyData[1];
	const byte *pbyPacketData = pbyData + 2;
	uint32 uLenPacket = uLenData - 2;

	//	AddDebugLogLine( false, _T("Processing UDP Packet from %s port %ld : opcode length %ld", ipstr(senderAddress->sin_addr), ntohs(senderAddress->sin_port), uLenPacket);
	//	CMiscUtils::debugHexDump(pbyPacketData, uLenPacket);

	switch (byOpcode)
	{
		case KADEMLIA_BOOTSTRAP_REQ:
			if (thePrefs.GetDebugClientKadUDPLevel() > 0)
				DebugRecv("KADEMLIA_BOOTSTRAP_REQ", uIP, uUDPPort);
			Process_KADEMLIA_BOOTSTRAP_REQ(pbyPacketData, uLenPacket, uIP, uUDPPort);
			break;
		case KADEMLIA2_BOOTSTRAP_REQ:
			if (thePrefs.GetDebugClientKadUDPLevel() > 0)
				DebugRecv("KADEMLIA2_BOOTSTRAP_REQ", uIP, uUDPPort);
			Process_KADEMLIA2_BOOTSTRAP_REQ(uIP, uUDPPort);
			break;
		case KADEMLIA_BOOTSTRAP_RES:
			if (thePrefs.GetDebugClientKadUDPLevel() > 0)
				DebugRecv("KADEMLIA_BOOTSTRAP_RES", uIP, uUDPPort);
			Process_KADEMLIA_BOOTSTRAP_RES(pbyPacketData, uLenPacket);
			break;
		case KADEMLIA2_BOOTSTRAP_RES:
			if (thePrefs.GetDebugClientKadUDPLevel() > 0)
				DebugRecv("KADEMLIA2_BOOTSTRAP_RES", uIP, uUDPPort);
			Process_KADEMLIA2_BOOTSTRAP_RES(pbyPacketData, uLenPacket, uIP, uUDPPort);
			break;
		case KADEMLIA_HELLO_REQ:
			if (thePrefs.GetDebugClientKadUDPLevel() > 0)
				DebugRecv("KADEMLIA_HELLO_REQ", uIP, uUDPPort);
			Process_KADEMLIA_HELLO_REQ(pbyPacketData, uLenPacket, uIP, uUDPPort);
			break;
		case KADEMLIA2_HELLO_REQ:
			if (thePrefs.GetDebugClientKadUDPLevel() > 0)
				DebugRecv("KADEMLIA2_HELLO_REQ", uIP, uUDPPort);
			Process_KADEMLIA2_HELLO_REQ(pbyPacketData, uLenPacket, uIP, uUDPPort);
			break;
		case KADEMLIA_HELLO_RES:
			if (thePrefs.GetDebugClientKadUDPLevel() > 0)
				DebugRecv("KADEMLIA_HELLO_RES", uIP, uUDPPort);
			Process_KADEMLIA_HELLO_RES(pbyPacketData, uLenPacket, uIP, uUDPPort);
			break;
		case KADEMLIA2_HELLO_RES:
			if (thePrefs.GetDebugClientKadUDPLevel() > 0)
				DebugRecv("KADEMLIA2_HELLO_RES", uIP, uUDPPort);
			Process_KADEMLIA2_HELLO_RES(pbyPacketData, uLenPacket, uIP, uUDPPort);
			break;
		case KADEMLIA_REQ:
			if (thePrefs.GetDebugClientKadUDPLevel() > 0)
				DebugRecv("KADEMLIA_REQ", uIP, uUDPPort);
			Process_KADEMLIA_REQ(pbyPacketData, uLenPacket, uIP, uUDPPort);
			break;
		case KADEMLIA2_REQ:
			if (thePrefs.GetDebugClientKadUDPLevel() > 0)
				DebugRecv("KADEMLIA2_REQ", uIP, uUDPPort);
			Process_KADEMLIA2_REQ(pbyPacketData, uLenPacket, uIP, uUDPPort);
			break;
		case KADEMLIA_RES:
			if (thePrefs.GetDebugClientKadUDPLevel() > 0)
				DebugRecv("KADEMLIA_RES", uIP, uUDPPort);
			Process_KADEMLIA_RES(pbyPacketData, uLenPacket, uIP, uUDPPort);
			break;
		case KADEMLIA2_RES:
			if (thePrefs.GetDebugClientKadUDPLevel() > 0)
				DebugRecv("KADEMLIA2_RES", uIP, uUDPPort);
			Process_KADEMLIA2_RES(pbyPacketData, uLenPacket, uIP, uUDPPort);
			break;
		case KADEMLIA_SEARCH_REQ:
			if (thePrefs.GetDebugClientKadUDPLevel() > 0)
				DebugRecv("KADEMLIA_SEARCH_REQ", uIP, uUDPPort);
			Process_KADEMLIA_SEARCH_REQ(pbyPacketData, uLenPacket, uIP, uUDPPort);
			break;
		case KADEMLIA2_SEARCH_KEY_REQ:
			if (thePrefs.GetDebugClientKadUDPLevel() > 0)
				DebugRecv("KADEMLIA2_SEARCH_KEY_REQ", uIP, uUDPPort);
			Process_KADEMLIA2_SEARCH_KEY_REQ(pbyPacketData, uLenPacket, uIP, uUDPPort);
			break;
		case KADEMLIA2_SEARCH_SOURCE_REQ:
			if (thePrefs.GetDebugClientKadUDPLevel() > 0)
				DebugRecv("KADEMLIA2_SEARCH_SOURCE_REQ", uIP, uUDPPort);
			Process_KADEMLIA2_SEARCH_SOURCE_REQ(pbyPacketData, uLenPacket, uIP, uUDPPort);
			break;
		case KADEMLIA_SEARCH_RES:
			if (thePrefs.GetDebugClientKadUDPLevel() > 0)
				DebugRecv("KADEMLIA_SEARCH_RES", uIP, uUDPPort);
			Process_KADEMLIA_SEARCH_RES(pbyPacketData, uLenPacket);
			break;
		case KADEMLIA2_SEARCH_RES:
			if (thePrefs.GetDebugClientKadUDPLevel() > 0)
				DebugRecv("KADEMLIA2_SEARCH_RES", uIP, uUDPPort);
			Process_KADEMLIA2_SEARCH_RES(pbyPacketData, uLenPacket);
			break;
		case KADEMLIA_PUBLISH_REQ:
			if (thePrefs.GetDebugClientKadUDPLevel() > 0)
				DebugRecv("KADEMLIA_PUBLISH_REQ", uIP, uUDPPort);
			Process_KADEMLIA_PUBLISH_REQ(pbyPacketData, uLenPacket, uIP, uUDPPort);
			break;
		case KADEMLIA2_PUBLISH_KEY_REQ:
			if (thePrefs.GetDebugClientKadUDPLevel() > 0)
				DebugRecv("KADEMLIA2_PUBLISH_KEY_REQ", uIP, uUDPPort);
			Process_KADEMLIA2_PUBLISH_KEY_REQ(pbyPacketData, uLenPacket, uIP, uUDPPort);
			break;
		case KADEMLIA_PUBLISH_RES:
			if (thePrefs.GetDebugClientKadUDPLevel() > 0)
				DebugRecv("KADEMLIA_PUBLISH_RES", uIP, uUDPPort);
			Process_KADEMLIA_PUBLISH_RES(pbyPacketData, uLenPacket);
			break;
		case KADEMLIA_SEARCH_NOTES_REQ:
			if (thePrefs.GetDebugClientKadUDPLevel() > 0)
				DebugRecv("KADEMLIA_SEARCH_NOTES_REQ", uIP, uUDPPort);
			Process_KADEMLIA_SEARCH_NOTES_REQ(pbyPacketData, uLenPacket, uIP, uUDPPort);
			break;
		case KADEMLIA2_SEARCH_NOTES_REQ:
			if (thePrefs.GetDebugClientKadUDPLevel() > 0)
				DebugRecv("KADEMLIA2_SEARCH_NOTES_REQ", uIP, uUDPPort);
			Process_KADEMLIA2_SEARCH_NOTES_REQ(pbyPacketData, uLenPacket, uIP, uUDPPort);
			break;
		case KADEMLIA_SEARCH_NOTES_RES:
			if (thePrefs.GetDebugClientKadUDPLevel() > 0)
				DebugRecv("KADEMLIA_SEARCH_NOTES_RES", uIP, uUDPPort);
			Process_KADEMLIA_SEARCH_NOTES_RES(pbyPacketData, uLenPacket);
			break;
		case KADEMLIA_PUBLISH_NOTES_REQ:
			if (thePrefs.GetDebugClientKadUDPLevel() > 0)
				DebugRecv("KADEMLIA_PUBLISH_NOTES_REQ", uIP, uUDPPort);
			Process_KADEMLIA_PUBLISH_NOTES_REQ(pbyPacketData, uLenPacket, uIP, uUDPPort);
			break;
		case KADEMLIA2_PUBLISH_NOTES_REQ:
			if (thePrefs.GetDebugClientKadUDPLevel() > 0)
				DebugRecv("KADEMLIA2_PUBLISH_NOTES_REQ", uIP, uUDPPort);
			Process_KADEMLIA2_PUBLISH_NOTES_REQ(pbyPacketData, uLenPacket, uIP, uUDPPort);
			break;
		case KADEMLIA_PUBLISH_NOTES_RES:
			if (thePrefs.GetDebugClientKadUDPLevel() > 0)
				DebugRecv("KADEMLIA_PUBLISH_NOTES_RES", uIP, uUDPPort);
			Process_KADEMLIA_PUBLISH_NOTES_RES(pbyPacketData, uLenPacket);
			break;
		case KADEMLIA_FIREWALLED_REQ:
			if (thePrefs.GetDebugClientKadUDPLevel() > 0)
				DebugRecv("KADEMLIA_FIREWALLED_REQ", uIP, uUDPPort);
			Process_KADEMLIA_FIREWALLED_REQ(pbyPacketData, uLenPacket, uIP, uUDPPort);
			break;
		case KADEMLIA_FIREWALLED_RES:
			if (thePrefs.GetDebugClientKadUDPLevel() > 0)
				DebugRecv("KADEMLIA_FIREWALLED_RES", uIP, uUDPPort);
			Process_KADEMLIA_FIREWALLED_RES(pbyPacketData, uLenPacket);
			break;
		case KADEMLIA_FIREWALLED_ACK_RES:
			if (thePrefs.GetDebugClientKadUDPLevel() > 0)
				DebugRecv("KADEMLIA_FIREWALLED_ACK_RES", uIP, uUDPPort);
			Process_KADEMLIA_FIREWALLED_ACK_RES(uLenPacket);
			break;
		case KADEMLIA_FINDBUDDY_REQ:
			if (thePrefs.GetDebugClientKadUDPLevel() > 0)
				DebugRecv("KADEMLIA_FINDBUDDY_REQ", uIP, uUDPPort);
			Process_KADEMLIA_FINDBUDDY_REQ(pbyPacketData, uLenPacket, uIP, uUDPPort);
			break;
		case KADEMLIA_FINDBUDDY_RES:
			if (thePrefs.GetDebugClientKadUDPLevel() > 0)
				DebugRecv("KADEMLIA_FINDBUDDY_RES", uIP, uUDPPort);
			Process_KADEMLIA_FINDBUDDY_RES(pbyPacketData, uLenPacket, uIP, uUDPPort);
			break;
		case KADEMLIA_CALLBACK_REQ:
			if (thePrefs.GetDebugClientKadUDPLevel() > 0)
				DebugRecv("KADEMLIA_CALLBACK_REQ", uIP, uUDPPort);
			Process_KADEMLIA_CALLBACK_REQ(pbyPacketData, uLenPacket, uIP);
			break;
		default:
			{
				CString strError;
				strError.Format(_T("Unknown opcode %02x"), byOpcode);
				throw strError;
			}
	}
}

// Used only for Kad1.0
void CKademliaUDPListener::AddContact( const byte *pbyData, uint32 uLenData, uint32 uIP, uint16 uUDPPort, uint16 uTCPPort)
{
	CSafeMemFile fileIO( pbyData, uLenData);
	CUInt128 uID;
	fileIO.ReadUInt128(&uID);
	fileIO.ReadUInt32();
	fileIO.ReadUInt16();
	if( uTCPPort )
		fileIO.ReadUInt16();
	else
		uTCPPort = fileIO.ReadUInt16();
	fileIO.ReadUInt8();
	CKademlia::GetRoutingZone()->Add(uID, uIP, uUDPPort, uTCPPort, 0);
}

// Used only for Kad2.0
void CKademliaUDPListener::AddContact_KADEMLIA2 (const byte* pbyData, uint32 uLenData, uint32 uIP, uint16 uUDPPort)
{
	CByteIO byteIO(pbyData, uLenData);
	CUInt128 uID;
	byteIO.ReadUInt128(&uID);
	uint16 uTCPPort = byteIO.ReadUInt16();
	uint8 uVersion = byteIO.ReadByte();
	uint8 uTags = byteIO.ReadByte();
	while(uTags)
	{
		CKadTag* pTag = byteIO.ReadTag();
		delete pTag;
		--uTags;
	}
	CKademlia::GetRoutingZone()->Add(uID, uIP, uUDPPort, uTCPPort, uVersion);
}

// Used only for Kad1.0
void CKademliaUDPListener::AddContacts( const byte *pbyData, uint32 uLenData, uint16 uNumContacts)
{
	CSafeMemFile fileIO( pbyData, uLenData );
	CRoutingZone *pRoutingZone = CKademlia::GetRoutingZone();
	CUInt128 uID;
	for (uint16 iIndex=0; iIndex<uNumContacts; iIndex++)
	{
		fileIO.ReadUInt128(&uID);
		uint32 uIP = fileIO.ReadUInt32();
		uint16 uUDPPort = fileIO.ReadUInt16();
		uint16 uTCPPort = fileIO.ReadUInt16();
		fileIO.ReadUInt8();
		pRoutingZone->Add(uID, uIP, uUDPPort, uTCPPort, 0);
	}
}

⌨️ 快捷键说明

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