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

📄 routingzone.cpp

📁 电驴的MAC源代码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
//// This file is part of aMule Project//// Copyright (c) 2004-2008 Angel Vidal ( 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// This work is based on the java implementation of the Kademlia protocol.// Kademlia: Peer-to-peer routing based on the XOR metric// Copyright (C) 2002  Petar Maymounkov [petar@post.harvard.edu]// http://kademlia.scs.cs.nyu.edu// 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..*//** * The *Zone* is just a node in a binary tree of *Zone*s. * Each zone is either an internal node or a leaf node. * Internal nodes have "bin == null" and "subZones[i] != null", * leaf nodes have "subZones[i] == null" and "bin != null". *  * All key unique id's are relative to the center (self), which * is considered to be 000..000 */#include "RoutingZone.h"#include <protocol/kad/Client2Client/UDP.h>#include <protocol/kad2/Client2Client/UDP.h>#include <common/Macros.h>#include "Contact.h"#include "RoutingBin.h"#include "../kademlia/Defines.h"#include "../kademlia/SearchManager.h"#include "../kademlia/UDPFirewallTester.h"#include "../net/KademliaUDPListener.h"#include "../utils/KadUDPKey.h"#include "../../amule.h"#include "../../CFile.h"#include "../../Logger.h"#include "../../NetworkFunctions.h"#include "../../IPFilter.h"#include "../../RandomFunctions.h"#include <cmath>////////////////////////////////////////using namespace Kademlia;////////////////////////////////////////// This is just a safety precaution#define CONTACT_FILE_LIMIT	500wxString CRoutingZone::m_filename;CUInt128 CRoutingZone::me((uint32_t)0);CRoutingZone::CRoutingZone(){	// Can only create routing zone after prefs	// Set our KadID for creating the contact tree	me = CKademlia::GetPrefs()->GetKadID();	// Set the preference file name.	m_filename = theApp->ConfigDir + wxT("nodes.dat");	Init(NULL, 0, CUInt128((uint32_t)0));}void CRoutingZone::Init(CRoutingZone *super_zone, int level, const CUInt128& zone_index){	// Init all Zone vars	// Set this zone's parent	m_superZone = super_zone;	// Set this zone's level	m_level = level;	// Set this zone's CUInt128 index	m_zoneIndex = zone_index;	// Mark this zone as having no leafs.	m_subZones[0] = NULL;	m_subZones[1] = NULL;	// Create a new contact bin as this is a leaf.	m_bin = new CRoutingBin();	// Set timer so that zones closer to the root are processed earlier.	m_nextSmallTimer = time(NULL) + m_zoneIndex.Get32BitChunk(3);	// Start this zone.	StartTimer();	// If we are initializing the root node, read in our saved contact list.	if ((m_superZone == NULL) && (m_filename.Length() > 0)) {		ReadFile();	}}CRoutingZone::~CRoutingZone(){	// Root node is processed first so that we can write our contact list and delete all branches.	if ((m_superZone == NULL) && (m_filename.Length() > 0)) {		WriteFile();	}	// If this zone is a leaf, delete our contact bin.	if (IsLeaf()) {		delete m_bin;	} else {		// If this zone is a branch, delete its leafs.		delete m_subZones[0];		delete m_subZones[1];	}}void CRoutingZone::ReadFile(const wxString& specialNodesdat){	if (m_superZone != NULL || (m_filename.IsEmpty() && specialNodesdat.IsEmpty())) {		wxFAIL;		return;	}	bool doHaveVerifiedContacts = false;	// Read in the saved contact list	try {		uint32_t numContacts = 0;		uint32_t validContacts = 0;		CFile file;		if (CPath::FileExists(specialNodesdat.IsEmpty() ? m_filename : specialNodesdat) && file.Open(m_filename, CFile::read)) {			// Get how many contacts in the saved list.			// NOTE: Older clients put the number of contacts here...			//       Newer clients always have 0 here to prevent older clients from reading it.			numContacts = file.ReadUInt32();			uint32_t fileVersion = 0;			if (numContacts == 0) {				if (file.GetLength() >= 8) {					fileVersion = file.ReadUInt32();					if (fileVersion == 3) {						uint32_t bootstrapEdition = file.ReadUInt32();						if (bootstrapEdition == 1) {							// this is a special bootstrap-only nodes.dat, handle it in a separate reading function							ReadBootstrapNodesDat(file);							file.Close();							return;						}					}					if (fileVersion >= 1 && fileVersion <= 3) {						numContacts = file.ReadUInt32();					}				}			}			if (numContacts != 0 && numContacts * 25 <= (file.GetLength() - file.GetPosition())) {				for (uint32_t i = 0; i < numContacts; i++) {					CUInt128 id = file.ReadUInt128();					uint32_t ip = file.ReadUInt32();					uint16_t udpPort = file.ReadUInt16();					uint16_t tcpPort = file.ReadUInt16();					uint8_t type = 0;					uint8_t contactVersion = 0;					if (fileVersion >= 1) {						contactVersion = file.ReadUInt8();					} else {						type = file.ReadUInt8();					}					CKadUDPKey kadUDPKey;					bool verified = false;					if (fileVersion >= 2) {						kadUDPKey.ReadFromFile(file);						verified = file.ReadUInt8() != 0;						if (verified) {							doHaveVerifiedContacts = true;						}					}					// IP appears valid					if (type < 4) {						if(IsGoodIPPort(wxUINT32_SWAP_ALWAYS(ip),udpPort)) {							if (!theApp->ipfilter->IsFiltered(wxUINT32_SWAP_ALWAYS(ip)) &&							    !(udpPort == 53 && contactVersion <= 5 /*No DNS Port without encryption*/)) {								// This was not a dead contact, inc counter if add was successful								if (AddUnfiltered(id, ip, udpPort, tcpPort, contactVersion, kadUDPKey, verified, false, true, false)) {									validContacts++;								}							}						}					}				}			}			file.Close();			AddLogLineM(false, wxString::Format(wxPLURAL("Read %u Kad contact", "Read %u Kad contacts", validContacts), validContacts));			if (!doHaveVerifiedContacts) {				AddDebugLogLineM(false, logKadRouting, wxT("No verified contacts found in nodes.dat - might be an old file version. Setting all contacts verified for this time to speed up Kad bootstrapping."));				SetAllContactsVerified();			}		}		if (numContacts == 0) {			AddDebugLogLineM(false, logKadRouting, wxT("Error while reading Kad contacts - 0 entries"));		}	} catch (const CSafeIOException& e) {		AddDebugLogLineM(false, logKadRouting, wxT("IO error in CRoutingZone::readFile: ") + e.what());	}}void CRoutingZone::ReadBootstrapNodesDat(CFileDataIO& file){	// Bootstrap versions of nodes.dat files are in the style of version 1 nodes.dats. The difference is that	// they will contain more contacts, 500-1000 instead of 50, and those contacts are not added into the routing table	// but used to sent Bootstrap packets to. The advantage is that on a list with a high ratio of dead nodes,	// we will be able to bootstrap faster than on a normal nodes.dat and more important, if we would deliver	// a normal nodes.dat with eMule, those 50 nodes would be kinda DDOSed because everyone adds them to their routing	// table, while with this style, we don't actually add any of the contacts to our routing table in the end and we	// ask only one of those 1000 contacts one time (well or more until we find an alive one).	if (!CKademlia::s_bootstrapList.empty()){		wxFAIL;		return;	}	uint32_t numContacts = file.ReadUInt32();	if (numContacts != 0 && numContacts * 25 == (file.GetLength() - file.GetPosition())) {		uint32_t validContacts = 0;		while (numContacts) {			CUInt128 id = file.ReadUInt128();			uint32_t ip = file.ReadUInt32();			uint16_t udpPort = file.ReadUInt16();			uint16_t tcpPort = file.ReadUInt16();			uint8_t contactVersion = file.ReadUInt8();			if (::IsGoodIPPort(wxUINT32_SWAP_ALWAYS(ip), udpPort)) {				if (!theApp->ipfilter->IsFiltered(wxUINT32_SWAP_ALWAYS(ip)) &&				    !(udpPort == 53 && contactVersion <= 5) && 				    (contactVersion > 1))	// only kad2 nodes				{					// we want the 50 nodes closest to our own ID (provides randomness between different users and gets has good chances to get a bootstrap with close Nodes which is a nice start for our routing table) 					CUInt128 distance = me;					distance ^= id;					validContacts++;					// don't bother if we already have 50 and the farest distance is smaller than this contact					if (CKademlia::s_bootstrapList.size() < 50 || CKademlia::s_bootstrapList.back()->GetDistance() > distance) {						// look where to put this contact into the proper position						bool inserted = false;						CContact* contact = new CContact(id, ip, udpPort, tcpPort, contactVersion, 0, false, me);						for (ContactList::iterator it = CKademlia::s_bootstrapList.begin(); it != CKademlia::s_bootstrapList.end(); ++it) {							if ((*it)->GetDistance() > distance) {								CKademlia::s_bootstrapList.insert(it, contact);								inserted = true;								break;							}						}						if (!inserted) {							wxASSERT(CKademlia::s_bootstrapList.size() < 50);							CKademlia::s_bootstrapList.push_back(contact);						} else if (CKademlia::s_bootstrapList.size() > 50) {							delete CKademlia::s_bootstrapList.back();							CKademlia::s_bootstrapList.pop_back();						}					}				}			}			numContacts--;		}		AddLogLineM(false, wxString::Format(wxPLURAL("Read %u Kad contact", "Read %u Kad contacts", CKademlia::s_bootstrapList.size()), CKademlia::s_bootstrapList.size()));		AddDebugLogLineM(false, logKadRouting, wxString::Format(wxT("Loaded Bootstrap nodes.dat, selected %u out of %u valid contacts"), CKademlia::s_bootstrapList.size(), validContacts));	}}

⌨️ 快捷键说明

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