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

📄 kademliaudplistener.cpp

📁 电驴的源程序,想学网络编程的可以下载来看看.
💻 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"
#include "../../ipfilter.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, bool bKad2)
{
	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, bKad2);
}

// Used by Kad1.0 and Kad 2.0
void CKademliaUDPListener::Bootstrap(uint32 uIP, uint16 uUDPPort, bool bKad2)
{
	if(bKad2)
	{
		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, bKad2);
	}
}

// Used by Kad1.0 and Kad 2.0
void CKademliaUDPListener::SendMyDetails(byte byOpcode, uint32 uIP, uint16 uUDPPort, bool bKad2)
{
	if(bKad2)
	{
		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);
	}
	else
	{
		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);
	}
}

// Kad1.0 & Kad2.0 currently.
void CKademliaUDPListener::FirewalledCheck(uint32 uIP, uint16 uUDPPort)
{
	CSafeMemFile fileIO(2);
	fileIO.WriteUInt16(thePrefs.GetPort());
//#ifdef _LOWTOLOW_SE
//	uint8 uUdpPortReq = 0x01;
//	fileIO.WriteUInt8(uUdpPortReq);
//#endif

	if (thePrefs.GetDebugClientKadUDPLevel() > 0)
		DebugSend("KADEMLIA_FIREWALLED_REQ", uIP, uUDPPort);
	SendPacket(&fileIO, KADEMLIA_FIREWALLED_REQ, uIP, uUDPPort);
	theApp.clientlist->AddKadFirewallRequest(ntohl(uIP));
}

// 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);
}

void CKademliaUDPListener::SendPublishSourcePacket(CContact* pContact, 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 (pContact->GetVersion() >= 4/*47c*/)
	{
		byteIO.WriteByte(KADEMLIA2_PUBLISH_SOURCE_REQ);
		byteIO.WriteUInt128(uTargetID);
		byteIO.WriteUInt128(uContactID);
		byteIO.WriteTagList(tags);
		if (thePrefs.GetDebugClientKadUDPLevel() > 0)
		{
			DebugSend("KADEMLIA2_PUBLISH_SOURCE_REQ", pContact->GetIPAddress(), pContact->GetUDPPort());
		}
	}
	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", pContact->GetIPAddress(), pContact->GetUDPPort());
		}
	}
	uint32 uLen = sizeof(byPacket) - byteIO.GetAvailable();
	SendPacket(byPacket, uLen,  pContact->GetIPAddress(), pContact->GetUDPPort());
}

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, uIP);
			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 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 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 KADEMLIA_SEARCH_NOTES_RES:
			if (thePrefs.GetDebugClientKadUDPLevel() > 0)
				DebugRecv("KADEMLIA_SEARCH_NOTES_RES", uIP, uUDPPort);
			Process_KADEMLIA_SEARCH_NOTES_RES(pbyPacketData, uLenPacket, uIP);
			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 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_KEY_REQ:
			if (thePrefs.GetDebugClientKadUDPLevel() > 0)
				DebugRecv("KADEMLIA2_PUBLISH_KEY_REQ", uIP, uUDPPort);
			Process_KADEMLIA2_PUBLISH_KEY_REQ(pbyPacketData, uLenPacket, uIP, uUDPPort);
			break;
		case KADEMLIA2_PUBLISH_SOURCE_REQ:
			if (thePrefs.GetDebugClientKadUDPLevel() > 0)
				DebugRecv("KADEMLIA2_PUBLISH_SOURCE_REQ", uIP, uUDPPort);
			Process_KADEMLIA2_PUBLISH_SOURCE_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_RES:
			if (thePrefs.GetDebugClientKadUDPLevel() > 0)
				DebugRecv("KADEMLIA_PUBLISH_RES", uIP, uUDPPort);
			Process_KADEMLIA_PUBLISH_RES(pbyPacketData, uLenPacket, uIP);
			break;
		case KADEMLIA_PUBLISH_NOTES_RES:
			if (thePrefs.GetDebugClientKadUDPLevel() > 0)
				DebugRecv("KADEMLIA_PUBLISH_NOTES_RES", uIP, uUDPPort);
			Process_KADEMLIA_PUBLISH_NOTES_RES(pbyPacketData, uLenPacket, uIP);
			break;
		case KADEMLIA2_PUBLISH_RES:
			if (thePrefs.GetDebugClientKadUDPLevel() > 0)
				DebugRecv("KADEMLIA2_PUBLISH_RES", uIP, uUDPPort);
			Process_KADEMLIA2_PUBLISH_RES(pbyPacketData, uLenPacket, uIP);
			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, uIP);
			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, bool bUpdate)
{
	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, bUpdate);
}

// Used only for Kad2.0
void CKademliaUDPListener::AddContact_KADEMLIA2 (const byte* pbyData, uint32 uLenData, uint32 uIP, uint16 uUDPPort, bool bUpdate)
{
	CByteIO byteIO(pbyData, uLenData);
	CUInt128 uID;
	byteIO.ReadUInt128(&uID);

⌨️ 快捷键说明

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