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

📄 kademliaudplistener.cpp

📁 电驴的MAC源代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
//// This file is part of aMule Project//// Copyright (c) 2004-2008 Angel Vidal (Kry) ( kry@amule.org )// Copyright (c) 2004-2008 aMule Project ( http://www.amule-project.net )// Copyright (C)2003 Barry Dunne (http://www.emule-project.net)// Copyright (C)2007-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, 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, pleasepost 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 knowingwhat 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 advertisethere client on the eMule forum..*/#include <wx/wx.h>#include "KademliaUDPListener.h"#include <protocol/Protocols.h>#include <protocol/kad/Constants.h>#include <protocol/kad/Client2Client/UDP.h>#include <protocol/kad2/Constants.h>#include <protocol/kad2/Client2Client/UDP.h>#include <protocol/ed2k/Client2Client/TCP.h> // OP_CALLBACK is sent in some cases.#include <common/Macros.h>#include <common/Format.h>#include <tags/FileTags.h>#include "../routing/Contact.h"#include "../routing/RoutingZone.h"#include "../kademlia/Indexed.h"#include "../kademlia/Defines.h"#include "../kademlia/UDPFirewallTester.h"#include "../utils/KadUDPKey.h"#include "../utils/KadClientSearcher.h"#include "../../amule.h"#include "../../ClientUDPSocket.h"#include "../../Packet.h"#include "../../ClientList.h"#include "../../Statistics.h"#include "../../MemFile.h"#include "../../updownclient.h"#include "../../ClientTCPSocket.h"#include "../../Logger.h"#include "../../Preferences.h"#include "../../ScopedPtr.h"#include "../../IPFilter.h"#include <wx/tokenzr.h>#define THIS_DEBUG_IS_JUST_FOR_KRY_DONT_TOUCH_IT_KTHX 0#if defined(__SUNPRO_CC)#define __FUNCTION__ __FILE__+__LINE__#endif#define CHECK_PACKET_SIZE(OP, SIZE) \	if (lenPacket OP (uint32_t)(SIZE)) \		throw wxString::Format(wxT("***NOTE: Received wrong size (%u) packet in "), lenPacket) + wxString::FromAscii(__FUNCTION__)#define CHECK_PACKET_MIN_SIZE(SIZE)	CHECK_PACKET_SIZE(<, SIZE)#define CHECK_PACKET_EXACT_SIZE(SIZE)	CHECK_PACKET_SIZE(!=, SIZE)#define CHECK_TRACKED_PACKET(OPCODE) \	if (!IsOnOutTrackList(ip, OPCODE)) \		throw wxString::Format(wxT("***NOTE: Received unrequested response packet, size (%u) in "), lenPacket) + wxString::FromAscii(__FUNCTION__)////////////////////////////////////////using namespace Kademlia;////////////////////////////////////////CKademliaUDPListener::~CKademliaUDPListener(){	// report timeout to all pending FetchNodeIDRequests	for (FetchNodeIDList::iterator it = m_fetchNodeIDRequests.begin(); it != m_fetchNodeIDRequests.end(); ++it) {		it->requester->KadSearchNodeIDByIPResult(KCSR_TIMEOUT, NULL);	}}// Used by Kad1.0 and Kad2.0void CKademliaUDPListener::Bootstrap(uint32_t ip, uint16_t port, bool kad2, uint8_t kadVersion, const CUInt128* cryptTargetID){	wxASSERT(ip);	if (kad2) {		DebugSend(Kad2BootstrapReq, ip, port);		CMemFile bio(0);		if (kadVersion >= 6) {			SendPacket(bio, KADEMLIA2_BOOTSTRAP_REQ, ip, port, 0, cryptTargetID);		} else {			SendPacket(bio, KADEMLIA2_BOOTSTRAP_REQ, ip, port, 0, NULL);		}	} else {		DebugSend(KadBootstrapReq, ip, port);		SendMyDetails(KADEMLIA_BOOTSTRAP_REQ, ip, port, 0, 0, NULL, false);	}}// Used by Kad1.0 and Kad2.0void CKademliaUDPListener::SendMyDetails(uint8_t opcode, uint32_t ip, uint16_t port, uint8_t kadVersion, const CKadUDPKey& targetKey, const CUInt128* cryptTargetID, bool requestAckPacket){	CMemFile packetdata;	packetdata.WriteUInt128(CKademlia::GetPrefs()->GetKadID());		if (kadVersion > 0) {		packetdata.WriteUInt16(thePrefs::GetPort());		packetdata.WriteUInt8(KADEMLIA_VERSION);		// Tag Count.		uint8_t tagCount = 0;		if (!CKademlia::GetPrefs()->GetUseExternKadPort()) {			tagCount++;		}		if (kadVersion >= 8 && (requestAckPacket || CKademlia::GetPrefs()->GetFirewalled() || CUDPFirewallTester::IsFirewalledUDP(true))) {			tagCount++;		}		packetdata.WriteUInt8(tagCount);		if (!CKademlia::GetPrefs()->GetUseExternKadPort()) {			packetdata.WriteTag(CTagVarInt(TAG_SOURCEUPORT, CKademlia::GetPrefs()->GetInternKadPort()));		}		if (kadVersion >= 8 && (requestAckPacket || CKademlia::GetPrefs()->GetFirewalled() || CUDPFirewallTester::IsFirewalledUDP(true))) {			// if we're firewalled we send this tag, so the other client doesn't add us to his routing table (if UDP firewalled) and for statistics reasons (TCP firewalled)			// 5 - reserved (!)			// 1 - requesting HELLO_RES_ACK			// 1 - TCP firewalled			// 1 - UDP firewalled			packetdata.WriteTag(CTagVarInt(TAG_KADMISCOPTIONS, (uint8_t)(				(requestAckPacket ? 1 : 0) << 2 |				(CKademlia::GetPrefs()->GetFirewalled() ? 1 : 0) << 1 |				(CUDPFirewallTester::IsFirewalledUDP(true) ? 1 : 0)			)));		}		// packetdata.WriteTag(CKadTagUInt(TAG_USER_COUNT, CKademlia::GetPrefs()->GetKademliaUsers()));		// packetdata.WriteTag(CKadTagUInt(TAG_FILE_COUNT, CKademlia::GetPrefs()->GetKademliaFiles()));		if (kadVersion >= 6) {			if (cryptTargetID == NULL || *cryptTargetID == 0) {				AddDebugLogLineM(false, logClientKadUDP, wxT("Sending hello response to crypt enabled Kad Node which provided an empty NodeID: ") + Uint32toStringIP(wxUINT32_SWAP_ALWAYS(ip)) + wxString::Format(wxT(" (%u)"), kadVersion));				SendPacket(packetdata, opcode, ip, port, targetKey, NULL);			} else {				SendPacket(packetdata, opcode, ip, port, targetKey, cryptTargetID);			}		} else {			SendPacket(packetdata, opcode, ip, port, 0, NULL);			wxASSERT(targetKey.IsEmpty());		}	} else {		wxASSERT(!requestAckPacket);		packetdata.WriteUInt32(CKademlia::GetPrefs()->GetIPAddress());		packetdata.WriteUInt16(thePrefs::GetEffectiveUDPPort());		packetdata.WriteUInt16(thePrefs::GetPort());		packetdata.WriteUInt8(0);		SendPacket(packetdata, opcode, ip, port, 0, NULL);	}}// Kad1.0 and Kad2.0 currently.void CKademliaUDPListener::FirewalledCheck(uint32_t ip, uint16_t port, const CKadUDPKey& senderKey, uint8_t kadVersion){	if (kadVersion > 6) {		// new opcode since 0.49a with extended informations to support obfuscated connections properly		CMemFile packetdata(19);		packetdata.WriteUInt16(thePrefs::GetPort());		packetdata.WriteUInt128(CKademlia::GetPrefs()->GetClientHash());		packetdata.WriteUInt8(CPrefs::GetMyConnectOptions(true, false));		DebugSend(KadFirewalled2Req, ip, port);		SendPacket(packetdata, KADEMLIA_FIREWALLED2_REQ, ip, port, senderKey, NULL);	} else {		CMemFile packetdata(2);		packetdata.WriteUInt16(thePrefs::GetPort());		DebugSend(KadFirewalledReq, ip, port);		SendPacket(packetdata, KADEMLIA_FIREWALLED_REQ, ip, port, senderKey, NULL);	}	theApp->clientlist->AddKadFirewallRequest(wxUINT32_SWAP_ALWAYS(ip));}void CKademliaUDPListener::SendNullPacket(uint8_t opcode, uint32_t ip, uint16_t port, const CKadUDPKey& targetKey, const CUInt128* cryptTargetID){	CMemFile packetdata(0);	SendPacket(packetdata, opcode, ip, port, targetKey, cryptTargetID);}void CKademliaUDPListener::SendPublishSourcePacket(const CContact& contact, const CUInt128 &targetID, const CUInt128 &contactID, const TagPtrList& tags){	uint8_t opcode;	CMemFile packetdata;	packetdata.WriteUInt128(targetID);	if (contact.GetVersion() >= 4/*47c*/) {		opcode = KADEMLIA2_PUBLISH_SOURCE_REQ;		packetdata.WriteUInt128(contactID);		packetdata.WriteTagPtrList(tags);		DebugSend(Kad2PublishSrcReq, contact.GetIPAddress(), contact.GetUDPPort());	} else {		opcode = KADEMLIA_PUBLISH_REQ;		//We only use this for publishing sources now.. So we always send one here..		packetdata.WriteUInt16(1);		packetdata.WriteUInt128(contactID);		packetdata.WriteTagPtrList(tags);		DebugSend(KadPublishReq, contact.GetIPAddress(), contact.GetUDPPort());	}	if (contact.GetVersion() >= 6) {	// obfuscated ?		CUInt128 clientID = contact.GetClientID();		SendPacket(packetdata, opcode, contact.GetIPAddress(), contact.GetUDPPort(), contact.GetUDPKey(), &clientID);	} else {		SendPacket(packetdata, opcode, contact.GetIPAddress(), contact.GetUDPPort(), 0, NULL);	}}void CKademliaUDPListener::ProcessPacket(const uint8_t* data, uint32_t lenData, uint32_t ip, uint16_t port, bool validReceiverKey, const CKadUDPKey& senderKey){	// we do not accept (<= 0.48a) unencrypted incoming packets from port 53 (DNS) to avoid attacks based on DNS protocol confusion	if (port == 53 && senderKey.IsEmpty()) {#ifdef __DEBUG__		AddDebugLogLineM(false, logKadPacketTracking, wxT("Dropping incoming unencrypted packet on port 53 (DNS), IP: ") + Uint32toStringIP(wxUINT32_SWAP_ALWAYS(ip)));#endif		return;	}	//Update connection state only when it changes.	bool curCon = CKademlia::GetPrefs()->HasHadContact();	CKademlia::GetPrefs()->SetLastContact();	CUDPFirewallTester::Connected();	if( curCon != CKademlia::GetPrefs()->HasHadContact()) {		theApp->ShowConnectionState();	}	uint8_t opcode = data[1];	const uint8_t *packetData = data + 2;	uint32_t lenPacket = lenData - 2;	if (!InTrackListIsAllowedPacket(ip, opcode, validReceiverKey)) {		return;	}	switch (opcode) {		case KADEMLIA_BOOTSTRAP_REQ:			DebugRecv(KadBootstrapReq, ip, port);			ProcessBootstrapRequest(packetData, lenPacket, ip, port);			break;		case KADEMLIA2_BOOTSTRAP_REQ:			DebugRecv(Kad2BootstrapReq, ip, port);			Process2BootstrapRequest(ip, port, senderKey);			break;		case KADEMLIA_BOOTSTRAP_RES:			DebugRecv(KadBootstrapRes, ip, port);			ProcessBootstrapResponse(packetData, lenPacket, ip);			break;		case KADEMLIA2_BOOTSTRAP_RES:			DebugRecv(Kad2BootstrapRes, ip, port);			Process2BootstrapResponse(packetData, lenPacket, ip, port, senderKey, validReceiverKey);			break;		case KADEMLIA_HELLO_REQ:			DebugRecv(KadHelloReq, ip, port);			ProcessHelloRequest(packetData, lenPacket, ip, port);			break;		case KADEMLIA2_HELLO_REQ:			DebugRecv(Kad2HelloReq, ip, port);			Process2HelloRequest(packetData, lenPacket, ip, port, senderKey, validReceiverKey);			break;		case KADEMLIA_HELLO_RES:			DebugRecv(KadHelloRes, ip, port);			ProcessHelloResponse(packetData, lenPacket, ip, port);			break;		case KADEMLIA2_HELLO_RES:			DebugRecv(Kad2HelloRes, ip, port);			Process2HelloResponse(packetData, lenPacket, ip, port, senderKey, validReceiverKey);			break;		case KADEMLIA2_HELLO_RES_ACK:			DebugRecv(Kad2HelloResAck, ip, port);			Process2HelloResponseAck(packetData, lenPacket, ip, validReceiverKey);			break;		case KADEMLIA_REQ:			DebugRecv(KadReq, ip, port);			ProcessKademliaRequest(packetData, lenPacket, ip, port);			break;		case KADEMLIA2_REQ:			DebugRecv(Kad2Req, ip, port);			ProcessKademlia2Request(packetData, lenPacket, ip, port, senderKey);			break;		case KADEMLIA_RES:			DebugRecv(KadRes, ip, port);			ProcessKademliaResponse(packetData, lenPacket, ip, port);			break;		case KADEMLIA2_RES:			DebugRecv(Kad2Res, ip, port);			ProcessKademlia2Response(packetData, lenPacket, ip, port, senderKey);			break;		case KADEMLIA_SEARCH_REQ:			DebugRecv(KadSearchReq, ip, port);			ProcessSearchRequest(packetData, lenPacket, ip, port);			break;		case KADEMLIA_SEARCH_NOTES_REQ:			DebugRecv(KadSearchNotesReq, ip, port);			ProcessSearchNotesRequest(packetData, lenPacket, ip, port);			break;		case KADEMLIA2_SEARCH_NOTES_REQ:			DebugRecv(Kad2SearchNotesReq, ip, port);			Process2SearchNotesRequest(packetData, lenPacket, ip, port, senderKey);			break;		case KADEMLIA2_SEARCH_KEY_REQ:			DebugRecv(Kad2SearchKeyReq, ip, port);			Process2SearchKeyRequest(packetData, lenPacket, ip, port, senderKey);			break;		case KADEMLIA2_SEARCH_SOURCE_REQ:			DebugRecv(Kad2SearchSourceReq, ip, port);			Process2SearchSourceRequest(packetData, lenPacket, ip, port, senderKey);			break;		case KADEMLIA_SEARCH_RES:			DebugRecv(KadSearchRes, ip, port);			ProcessSearchResponse(packetData, lenPacket);			break;		case KADEMLIA_SEARCH_NOTES_RES:			DebugRecv(KadSearchNotesRes, ip, port);			ProcessSearchNotesResponse(packetData, lenPacket, ip);			break;		case KADEMLIA2_SEARCH_RES:			DebugRecv(Kad2SearchRes, ip, port);			Process2SearchResponse(packetData, lenPacket, senderKey);			break;		case KADEMLIA_PUBLISH_REQ:			DebugRecv(KadPublishReq, ip, port);			ProcessPublishRequest(packetData, lenPacket, ip, port);			break;		case KADEMLIA_PUBLISH_NOTES_REQ:			DebugRecv(KadPublishNotesReq, ip, port);			ProcessPublishNotesRequest(packetData, lenPacket, ip, port);			break;		case KADEMLIA2_PUBLISH_NOTES_REQ:			DebugRecv(Kad2PublishNotesReq, ip, port);			Process2PublishNotesRequest(packetData, lenPacket, ip, port, senderKey);			break;		case KADEMLIA2_PUBLISH_KEY_REQ:			DebugRecv(Kad2PublishKeyReq, ip, port);			Process2PublishKeyRequest(packetData, lenPacket, ip, port, senderKey);			break;		case KADEMLIA2_PUBLISH_SOURCE_REQ:			DebugRecv(Kad2PublishSourceReq, ip, port);			Process2PublishSourceRequest(packetData, lenPacket, ip, port, senderKey);			break;		case KADEMLIA_PUBLISH_RES:			DebugRecv(KadPublishRes, ip, port);			ProcessPublishResponse(packetData, lenPacket, ip);			break;		case KADEMLIA_PUBLISH_NOTES_RES:			DebugRecv(KadPublishNotesRes, ip, port);

⌨️ 快捷键说明

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