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

📄 kademliaudplistener.cpp

📁 电驴的MAC源代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
			ProcessPublishNotesResponse(packetData, lenPacket, ip);			break;		case KADEMLIA2_PUBLISH_RES:			DebugRecv(Kad2PublishRes, ip, port);			Process2PublishResponse(packetData, lenPacket, ip, port, senderKey);			break;		case KADEMLIA_FIREWALLED_REQ:			DebugRecv(KadFirewalledReq, ip, port);			ProcessFirewalledRequest(packetData, lenPacket, ip, port, senderKey);			break;		case KADEMLIA_FIREWALLED2_REQ:			DebugRecv(KadFirewalled2Req, ip, port);			ProcessFirewalled2Request(packetData, lenPacket, ip, port, senderKey);			break;		case KADEMLIA_FIREWALLED_RES:			DebugRecv(KadFirewalledRes, ip, port);			ProcessFirewalledResponse(packetData, lenPacket, ip, senderKey);			break;		case KADEMLIA_FIREWALLED_ACK_RES:			DebugRecv(KadFirewalledAck, ip, port);			ProcessFirewalledAckResponse(lenPacket);			break;		case KADEMLIA_FINDBUDDY_REQ:			DebugRecv(KadFindBuddyReq, ip, port);			ProcessFindBuddyRequest(packetData, lenPacket, ip, port, senderKey);			break;		case KADEMLIA_FINDBUDDY_RES:			DebugRecv(KadFindBuddyRes, ip, port);			ProcessFindBuddyResponse(packetData, lenPacket, ip, port, senderKey);			break;		case KADEMLIA_CALLBACK_REQ:			DebugRecv(KadCallbackReq, ip, port);			ProcessCallbackRequest(packetData, lenPacket, ip, port, senderKey);			break;		case KADEMLIA2_PING:			DebugRecv(Kad2Ping, ip, port);			Process2Ping(ip, port, senderKey);			break;		case KADEMLIA2_PONG:			DebugRecv(Kad2Pong, ip, port);			Process2Pong(packetData, lenPacket, ip);			break;		case KADEMLIA2_FIREWALLUDP:			DebugRecv(Kad2FirewallUDP, ip, port);			Process2FirewallUDP(packetData, lenPacket, ip);			break;		default: {			throw wxString::Format(wxT("Unknown opcode %02x on CKademliaUDPListener::ProcessPacket()"), opcode);		}	}}// Used only for Kad1.0bool CKademliaUDPListener::AddContact(const uint8_t *data, uint32_t lenData, uint32_t ip, uint16_t port, uint16_t tport, const CKadUDPKey& udpKey, bool& ipVerified, bool update, CUInt128* outContactID){	CMemFile bio(data, lenData);	CUInt128 id = bio.ReadUInt128();	if (outContactID != NULL) {		*outContactID = id;	}	bio.ReadUInt32();	bio.ReadUInt16();	if (tport) {		bio.ReadUInt16();	} else {		tport = bio.ReadUInt16();	}	bio.ReadUInt8();	//AddDebugLogLineM(false, logKadMain, wxT("Adding a contact with ip ") + Uint32_16toStringIP_Port(wxUINT32_SWAP_ALWAYS(ip),port));	// Ignore stated ip and port, use the address the packet came from	return CKademlia::GetRoutingZone()->Add(id, ip, port, tport, 0, udpKey, ipVerified, update, false, true);}// Used only for Kad2.0bool CKademliaUDPListener::AddContact2(const uint8_t *data, uint32_t lenData, uint32_t ip, uint16_t& port, uint8_t *outVersion, const CKadUDPKey& udpKey, bool& ipVerified, bool update, bool fromHelloReq, bool* outRequestsACK, CUInt128* outContactID){	if (outRequestsACK != 0) {		*outRequestsACK = false;	}	CMemFile bio(data, lenData);	CUInt128 id = bio.ReadUInt128();	if (outContactID != NULL) {		*outContactID = id;	}	uint16_t tport = bio.ReadUInt16();	uint8_t version = bio.ReadUInt8();	if (version == 0) {		throw wxString::Format(wxT("***NOTE: Received invalid Kademlia2 version (%u) in "), version) + wxString::FromAscii(__FUNCTION__);	}	if (outVersion != NULL) {		*outVersion = version;	}	bool udpFirewalled = false;	bool tcpFirewalled = false;	uint8_t tags = bio.ReadUInt8();	while (tags) {		CTag *tag = bio.ReadTag();		if (!tag->GetName().Cmp(TAG_SOURCEUPORT)) {			if (tag->IsInt() && (uint16_t)tag->GetInt() > 0) {				port = tag->GetInt();			}		} else if (!tag->GetName().Cmp(TAG_KADMISCOPTIONS)) {			if (tag->IsInt() && tag->GetInt() > 0) {				udpFirewalled = (tag->GetInt() & 0x01) > 0;				tcpFirewalled = (tag->GetInt() & 0x02) > 0;				if ((tag->GetInt() & 0x04) > 0) {					if (outRequestsACK != NULL) {						if (version >= 8) {							*outRequestsACK = true;						}					} else {						wxFAIL;					}				}			}		}		delete tag;		--tags;	}	// check if we are waiting for informations (nodeid) about this client and if so inform the requester	for (FetchNodeIDList::iterator it = m_fetchNodeIDRequests.begin(); it != m_fetchNodeIDRequests.end(); ++it) {		if (it->ip == ip && it->tcpPort == tport) {			//AddDebugLogLineM(false, logKadMain, wxT("Result Addcontact: ") + id.ToHexString());			uint8_t uchID[16];			id.ToByteArray(uchID);			it->requester->KadSearchNodeIDByIPResult(KCSR_SUCCEEDED, uchID);			m_fetchNodeIDRequests.erase(it);			break;		}	}	if (fromHelloReq && version >= 8) {		// this is just for statistic calculations. We try to determine the ratio of (UDP) firewalled users,		// by counting how many of all nodes which have us in their routing table (our own routing table is supposed		// to have no UDP firewalled nodes at all) and support the firewalled tag are firewalled themself.		// Obviously this only works if we are not firewalled ourself		CKademlia::GetPrefs()->StatsIncUDPFirewalledNodes(udpFirewalled);		CKademlia::GetPrefs()->StatsIncTCPFirewalledNodes(tcpFirewalled);	}	if (!udpFirewalled) {	// do not add (or update) UDP firewalled sources to our routing table		return CKademlia::GetRoutingZone()->Add(id, ip, port, tport, version, udpKey, ipVerified, update, false, true);	} else {		AddDebugLogLineM(false, logKadRouting, wxT("Not adding firewalled client to routing table (") + Uint32toStringIP(wxUINT32_SWAP_ALWAYS(ip)) + wxT(")"));		return false;	}}// Used only for Kad1.0void CKademliaUDPListener::AddContacts(const uint8_t *data, uint32_t lenData, uint16_t numContacts, bool update){	CMemFile bio(data, lenData);	CRoutingZone *routingZone = CKademlia::GetRoutingZone();	for (uint16_t i = 0; i < numContacts; i++) {		CUInt128 id = bio.ReadUInt128();		uint32_t ip = bio.ReadUInt32();		ip = wxUINT32_SWAP_ALWAYS(ip);		uint16_t port = bio.ReadUInt16();		uint16_t tport = bio.ReadUInt16();		bio.ReadUInt8();		bool verified = false;		//AddDebugLogLineM(false, logKadMain, wxT("Adding contact(s) with ip ") + Uint32_16toStringIP_Port(wxUINT32_SWAP_ALWAYS(ip),port));		routingZone->Add(id, ip, port, tport, 0, 0, verified, update, false, false);	}}// KADEMLIA_BOOTSTRAP_REQ// Used only for Kad1.0void CKademliaUDPListener::ProcessBootstrapRequest(const uint8_t *packetData, uint32_t lenPacket, uint32_t ip, uint16_t port){	// Verify packet is expected size	CHECK_PACKET_EXACT_SIZE(25);	// Add the sender to the list of contacts	bool verified = false;	AddContact(packetData, lenPacket, ip, port, 0, 0, verified, true, NULL);	// Get some contacts to return	ContactList contacts;	uint16_t numContacts = 1 + (uint16_t)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	CMemFile packetdata(527);	// Write packet info	packetdata.WriteUInt16(numContacts);	CContact *contact;	for (ContactList::const_iterator it = contacts.begin(); it != contacts.end(); ++it) {		contact = *it;		packetdata.WriteUInt128(contact->GetClientID());		packetdata.WriteUInt32(contact->GetIPAddress());		packetdata.WriteUInt16(contact->GetUDPPort());		packetdata.WriteUInt16(contact->GetTCPPort());		packetdata.WriteUInt8(contact->GetType());	}	packetdata.WriteUInt128(CKademlia::GetPrefs()->GetKadID());	packetdata.WriteUInt32(CKademlia::GetPrefs()->GetIPAddress());	packetdata.WriteUInt16(thePrefs::GetEffectiveUDPPort());	packetdata.WriteUInt16(thePrefs::GetPort());	packetdata.WriteUInt8(0);	// Send response	DebugSend(KadBootstrapRes, ip, port);	SendPacket(packetdata, KADEMLIA_BOOTSTRAP_RES, ip, port, 0, NULL);}// KADEMLIA2_BOOTSTRAP_REQ// Used only for Kad2.0void CKademliaUDPListener::Process2BootstrapRequest(uint32_t ip, uint16_t port, const CKadUDPKey& senderKey){	// Get some contacts to return	ContactList contacts;	uint16_t numContacts = (uint16_t)CKademlia::GetRoutingZone()->GetBootstrapContacts(&contacts, 20);	// Create response packet	//We only collect a max of 20 contacts here.. Max size is 521.	//2 + 25(20) + 19	CMemFile packetdata(521);	packetdata.WriteUInt128(CKademlia::GetPrefs()->GetKadID());	packetdata.WriteUInt16(thePrefs::GetPort());	packetdata.WriteUInt8(KADEMLIA_VERSION);	// Write packet info	packetdata.WriteUInt16(numContacts);	CContact *contact;	for (ContactList::const_iterator it = contacts.begin(); it != contacts.end(); ++it) {		contact = *it;		packetdata.WriteUInt128(contact->GetClientID());		packetdata.WriteUInt32(contact->GetIPAddress());		packetdata.WriteUInt16(contact->GetUDPPort());		packetdata.WriteUInt16(contact->GetTCPPort());		packetdata.WriteUInt8(contact->GetVersion());	}	// Send response	DebugSend(Kad2BootstrapRes, ip, port);	SendPacket(packetdata, KADEMLIA2_BOOTSTRAP_RES, ip, port, senderKey, NULL);}// KADEMLIA_BOOTSTRAP_RES// Used only for Kad1.0void CKademliaUDPListener::ProcessBootstrapResponse(const uint8_t *packetData, uint32_t lenPacket, uint32_t ip){	// Verify packet is expected size	CHECK_PACKET_MIN_SIZE(27);	CHECK_TRACKED_PACKET(KADEMLIA_BOOTSTRAP_REQ);	// How many contacts were given	CMemFile bio(packetData, lenPacket);	uint16_t numContacts = bio.ReadUInt16();	// Verify packet is expected size	if (lenPacket != (uint32_t)(2 + 25 * numContacts)) {		return;	}	// Add these contacts to the list.	AddContacts(packetData + 2, lenPacket - 2, numContacts, false);}// KADEMLIA2_BOOTSTRAP_RES// Used only for Kad2.0void CKademliaUDPListener::Process2BootstrapResponse(const uint8_t *packetData, uint32_t lenPacket, uint32_t ip, uint16_t port, const CKadUDPKey& senderKey, bool validReceiverKey){	CHECK_TRACKED_PACKET(KADEMLIA2_BOOTSTRAP_REQ);	CRoutingZone *routingZone = CKademlia::GetRoutingZone();	// How many contacts were given	CMemFile bio(packetData, lenPacket);	CUInt128 contactID = bio.ReadUInt128();	uint16_t tport = bio.ReadUInt16();	uint8_t version = bio.ReadUInt8();	// if we don't know any Contacts yet and try to Bootstrap, we assume that all contacts are verified,	// in order to speed up the connecting process. The attackvectors to exploit this are very small with no	// major effects, so that's a good trade	bool assumeVerified = CKademlia::GetRoutingZone()->GetNumContacts() == 0;	if (CKademlia::s_bootstrapList.empty()) {		routingZone->Add(contactID, ip, port, tport, version, senderKey, validReceiverKey, true, false, false);	}	uint16_t numContacts = bio.ReadUInt16();	while (numContacts) {		contactID = bio.ReadUInt128();		ip = bio.ReadUInt32();		port = bio.ReadUInt16();		tport = bio.ReadUInt16();		version = bio.ReadUInt8();		bool verified = assumeVerified;		routingZone->Add(contactID, ip, port, tport, version, 0, verified, false, false, false);		numContacts--;	}}// KADEMLIA_HELLO_REQ// Used in Kad1.0 onlyvoid CKademliaUDPListener::ProcessHelloRequest(const uint8_t *packetData, uint32_t lenPacket, uint32_t ip, uint16_t port){	// Verify packet is expected size	CHECK_PACKET_EXACT_SIZE(25);	// Add the sender to the list of contacts	bool validReceiverKey = false;	CUInt128 contactID;	bool addedOrUpdated = AddContact(packetData, lenPacket, ip, port, 0, 0, validReceiverKey, true, &contactID);	// Send response	DebugSend(KadHelloRes, ip, port);		SendMyDetails(KADEMLIA_HELLO_RES, ip, port, 0, 0, NULL, false);	if (addedOrUpdated && !validReceiverKey) {		// we need to verify this contact but it doesn't support HELLO_RES_ACK nor keys, do a little workaround		SendLegacyChallenge(ip, port, contactID, false);	}	// Check if firewalled	if (CKademlia::GetPrefs()->GetRecheckIP()) {		FirewalledCheck(ip, port, 0, 0);	}}// KADEMLIA2_HELLO_REQ// Used in Kad2.0 onlyvoid CKademliaUDPListener::Process2HelloRequest(const uint8_t *packetData, uint32_t lenPacket, uint32_t ip, uint16_t port, const CKadUDPKey& senderKey, bool validReceiverKey){	uint16_t dbgOldUDPPort = port;	uint8_t contactVersion = 0;	CUInt128 contactID;	bool addedOrUpdated = AddContact2(packetData, lenPacket, ip, port, &contactVersion, senderKey, validReceiverKey, true, true, NULL, &contactID); // might change (udp)port, validReceiverKey	wxASSERT(contactVersion >= 1);#ifdef __DEBUG__	if (dbgOldUDPPort != port) {		AddDebugLogLineM(false, logClientKadUDP, wxT("KadContact ") + Uint32toStringIP(wxUINT32_SWAP_ALWAYS(ip)) + wxString::Format(wxT(" uses his internal (%u) instead external (%u) UDP Port"), port, dbgOldUDPPort));	}#endif	DebugSend(Kad2HelloRes, ip, port);	// if this contact was added or updated (so with other words not filtered or invalid) to our routing table and did not already send a valid	// receiver key or is already verified in the routing table, we request an additional ACK package to complete a three-way-handshake and	// verify the remote IP	SendMyDetails(KADEMLIA2_HELLO_RES, ip, port, contactVersion, senderKey, &contactID, addedOrUpdated && !validReceiverKey);	if (addedOrUpdated && !validReceiverKey && contactVersion == 7 && !HasActiveLegacyChallenge(ip)) {		// Kad Version 7 doesn't support HELLO_RES_ACK but sender/receiver keys, so send a ping to validate		DebugSend(Kad2Ping, ip, port);		SendNullPacket(KADEMLIA2_PING, ip, port, senderKey, NULL);#ifdef __DEBUG__		CContact* contact = CKademlia::GetRoutingZone()->GetContact(contactID);		if (contact != NULL) {			if (contact->GetType() < 2) {				AddDebugLogLineM(false, logClientKadUDP, wxT("Sending (ping) challenge to a long known contact (should be verified already) - ") + Uint32toStringIP(wxUINT32_SWAP_ALWAYS(ip)));			}		} else {			wxFAIL;		}#endif	} else if (CKademlia::GetPrefs()->GetExternalKadPort() == 0 && contactVersion > 5) {	// do we need to find out our extern port?

⌨️ 快捷键说明

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