kademliaudplistener.cpp
来自「wxWidgets写的电驴」· C++ 代码 · 共 1,226 行 · 第 1/3 页
CPP
1,226 行
} else { //TODO: Filter tags entry->taglist.push_back(tag); } } tags--; } if (!strInfo.IsEmpty()) { AddDebugLogLineM(false, logClientKadUDP, strInfo); } } catch(...) { DebugClientOutput(wxT("CKademliaUDPListener::processPublishRequest"),ip,port); delete entry; throw; } if( entry->source == true ) { entry->lifetime = (uint32)time(NULL)+KADEMLIAREPUBLISHTIMES; if( indexed->AddSources(file, target, entry, load ) ) { flag = true; } else { delete entry; entry = NULL; } } else { entry->lifetime = (uint32)time(NULL)+KADEMLIAREPUBLISHTIMEK; if( indexed->AddKeyword(file, target, entry, load) ) { // This makes sure we send a publish response.. // This also makes sure we index all the files for this keyword. flag = true; } else { //We already indexed the maximum number of keywords. //We do not index anymore but we still send a success.. //Reason: Because if a VERY busy node tells the publisher it failed, //this busy node will spread to all the surrounding nodes causing popular //keywords to be stored on MANY nodes.. //So, once we are full, we will periodically clean our list until we can //begin storing again.. flag = true; delete entry; entry = NULL; } } count--; } if( flag ) { CMemFile bio2(17); bio2.WriteUInt128(file); bio2.WriteUInt8(load); AddDebugLogLineM(false, logClientKadUDP, CFormat(wxT("KadPublishRes %s")) % Uint32_16toStringIP_Port(wxUINT32_SWAP_ALWAYS(ip), port)); sendPacket( &bio2, KADEMLIA_PUBLISH_RES, ip, port); }}//KADEMLIA_PUBLISH_ACKvoid CKademliaUDPListener::processPublishResponse (const byte *packetData, uint32 lenPacket, uint32 ip, uint16 port){ // Verify packet is expected size if (lenPacket < 16) { throw wxString::Format(wxT("***NOTE: Received wrong size (%u) packet in "), lenPacket) + wxString::FromAscii(__FUNCTION__); } // Set contact to alive. CKademlia::getRoutingZone()->setAlive(ip, port); CMemFile bio((byte*)packetData, lenPacket); CUInt128 file = bio.ReadUInt128(); bool loadResponse = false; uint8 load = 0; if( bio.GetLength() > bio.GetPosition() ) { loadResponse = true; load = bio.ReadUInt8(); } CSearchManager::processPublishResult(file, load, loadResponse);}//KADEMLIA_SRC_NOTES_REQvoid CKademliaUDPListener::processSearchNotesRequest (const byte *packetData, uint32 lenPacket, uint32 ip, uint16 port){ // Verify packet is expected size if (lenPacket < 32) { throw wxString::Format(wxT("***NOTE: Received wrong size (%u) packet in "), lenPacket) + wxString::FromAscii(__FUNCTION__); } CMemFile bio((byte*)packetData, lenPacket); CUInt128 target = bio.ReadUInt128(); CUInt128 source = bio.ReadUInt128(); CKademlia::getIndexed()->SendValidNoteResult(target, source, ip, port);}//KADEMLIA_SRC_NOTES_RESvoid CKademliaUDPListener::processSearchNotesResponse (const byte *packetData, uint32 lenPacket, uint32 ip, uint16 port){ // Verify packet is expected size if (lenPacket < 37) { throw wxString::Format(wxT("***NOTE: Received wrong size (%u) packet in "), lenPacket) + wxString::FromAscii(__FUNCTION__); } // Set contact to alive. CKademlia::getRoutingZone()->setAlive(ip, port); // What search does this relate to CByteIO bio(packetData, lenPacket); CUInt128 target; bio.readUInt128(&target); uint16 count = bio.readUInt16(); while( count > 0 ) { // What is the answer CUInt128 answer; bio.readUInt128(&answer); // Get info about answer // NOTE: this is the one and only place in Kad where we allow string conversion to local code page in // case we did not receive an UTF8 string. this is for backward compatibility for search results which are // supposed to be 'viewed' by user only and not feed into the Kad engine again! // If that tag list is once used for something else than for viewing, special care has to be taken for any // string conversion! TagList* tags = new TagList; try{ bio.readTagList(tags, true/*bOptACP*/); } catch(...){ DebugClientOutput(wxT("CKademliaUDPListener::processSearchNotesResponse"),ip,port); deleteTagListEntries(tags); delete tags; tags = NULL; throw; } CSearchManager::processResult(target, ip, port, answer, tags); count--; }}//KADEMLIA_PUB_NOTES_REQvoid CKademliaUDPListener::processPublishNotesRequest (const byte *packetData, uint32 lenPacket, uint32 ip, uint16 port){ // Verify packet is expected size if (lenPacket < 37) { throw wxString::Format(wxT("***NOTE: Received wrong size (%u) packet in "), lenPacket) + wxString::FromAscii(__FUNCTION__); } if( CKademlia::getPrefs()->getFirewalled() ) { //We are firewalled. We should not index this entry and give publisher a false report. return; } CByteIO bio(packetData, lenPacket); CUInt128 target; bio.readUInt128(&target); CUInt128 distance(CKademlia::getPrefs()->getKadID()); distance.XOR(target); if( thePrefs::FilterLanIPs() && distance.get32BitChunk(0) > SEARCHTOLERANCE) { return; } CUInt128 source; bio.readUInt128(&source); Kademlia::CEntry* entry = new Kademlia::CEntry(); try { entry->ip = ip; entry->udpport = port; entry->keyID.setValue(target); entry->sourceID.setValue(source); bio.readTagList(&entry->taglist); entry->source = false; } catch(...) { DebugClientOutput(wxT("CKademliaUDPListener::processPublishNotesRequest"),ip,port); delete entry; throw; } if( entry == NULL ) { throw wxString(wxT("CKademliaUDPListener::processPublishNotesRequest: entry == NULL")); } else if( entry->taglist.size() == 0 || entry->taglist.size() > 5) { delete entry; throw wxString(wxT("CKademliaUDPListener::processPublishNotesRequest: entry->taglist.size() == 0 || entry->taglist.size() > 5")); } uint8 load = 0; if( CKademlia::getIndexed()->AddNotes(target, source, entry, load ) ) { CMemFile bio2(17); bio2.WriteUInt128(target); bio2.WriteUInt8(load); AddDebugLogLineM(false, logClientKadUDP, CFormat(wxT("KadPublishNotesRes %s")) % Uint32_16toStringIP_Port(wxUINT32_SWAP_ALWAYS(ip), port)); sendPacket( &bio2, KADEMLIA_PUB_NOTES_RES, ip, port); } else { delete entry; }}//KADEMLIA_PUB_NOTES_RESvoid CKademliaUDPListener::processPublishNotesResponse (const byte *packetData, uint32 lenPacket, uint32 ip, uint16 port){ // Verify packet is expected size if (lenPacket < 16){ throw wxString::Format(wxT("***NOTE: Received wrong size (%u) packet in "), lenPacket) + wxString::FromAscii(__FUNCTION__); } // Set contact to alive. CKademlia::getRoutingZone()->setAlive(ip, port); CMemFile bio((byte*)packetData, lenPacket); CUInt128 file = bio.ReadUInt128(); bool loadResponse = false; uint8 load = 0; if( bio.GetLength() > bio.GetPosition() ) { loadResponse = true; load = bio.ReadUInt8(); } CSearchManager::processPublishResult(file, load, loadResponse);}//KADEMLIA_FIREWALLED_REQvoid CKademliaUDPListener::processFirewalledRequest (const byte *packetData, uint32 lenPacket, uint32 ip, uint16 port){ // Verify packet is expected size if (lenPacket != 2){ throw wxString::Format(wxT("***NOTE: Received wrong size (%u) packet in "), lenPacket) + wxString::FromAscii(__FUNCTION__); } CMemFile bio((byte*)packetData, lenPacket); uint16 tcpport = bio.ReadUInt16(); CContact contact; contact.setIPAddress(ip); contact.setTCPPort(tcpport); contact.setUDPPort(port); theApp.clientlist->RequestTCP(&contact); // Send response CMemFile bio2(4); bio2.WriteUInt32(ip); AddDebugLogLineM(false, logClientKadUDP, CFormat(wxT("KadFirewalledRes %s")) % Uint32_16toStringIP_Port(wxUINT32_SWAP_ALWAYS(ip), port)); sendPacket(&bio2, KADEMLIA_FIREWALLED_RES, ip, port);}//KADEMLIA_FIREWALLED_RESvoid CKademliaUDPListener::processFirewalledResponse (const byte *packetData, uint32 lenPacket, uint32 ip, uint16 port){ // Verify packet is expected size if (lenPacket != 4){ throw wxString::Format(wxT("***NOTE: Received wrong size (%u) packet in "), lenPacket) + wxString::FromAscii(__FUNCTION__); } // Set contact to alive. CKademlia::getRoutingZone()->setAlive(ip, port); CMemFile bio((byte*)packetData, lenPacket); uint32 firewalledIP = bio.ReadUInt32(); //Update con state only if something changes. if( CKademlia::getPrefs()->getIPAddress() != firewalledIP ) { CKademlia::getPrefs()->setIPAddress(firewalledIP); theApp.ShowConnectionState(); } CKademlia::getPrefs()->incRecheckIP();}//KADEMLIA_FIREWALLED_ACKvoid CKademliaUDPListener::processFirewalledResponse2 (const byte *WXUNUSED(packetData), uint32 lenPacket, uint32 ip, uint16 port){ // Verify packet is expected size if (lenPacket != 0) { throw wxString::Format(wxT("***NOTE: Received wrong size (%u) packet in "), lenPacket) + wxString::FromAscii(__FUNCTION__); } // Set contact to alive. CKademlia::getRoutingZone()->setAlive(ip, port); CKademlia::getPrefs()->incFirewalled();}//KADEMLIA_FINDBUDDY_REQvoid CKademliaUDPListener::processFindBuddyRequest (const byte *packetData, uint32 lenPacket, uint32 ip, uint16 port){ // Verify packet is expected size if (lenPacket < 34) { throw wxString::Format(wxT("***NOTE: Received wrong size (%u) packet in "), lenPacket) + wxString::FromAscii(__FUNCTION__); } if( CKademlia::getPrefs()->getFirewalled() ) { //We are firewalled but somehow we still got this packet.. Don't send a response.. return; } CMemFile bio((byte*)packetData, lenPacket); CUInt128 BuddyID = bio.ReadUInt128(); CUInt128 userID = bio.ReadUInt128(); uint16 tcpport = bio.ReadUInt16(); CContact contact; contact.setIPAddress(ip); contact.setTCPPort(tcpport); contact.setUDPPort(port); contact.setClientID(userID); theApp.clientlist->IncomingBuddy(&contact, &BuddyID); CMemFile bio2(34); bio2.WriteUInt128(BuddyID); bio2.WriteUInt128(CKademlia::getPrefs()->getClientHash()); bio2.WriteUInt16(thePrefs::GetPort()); AddDebugLogLineM(false, logClientKadUDP, CFormat(wxT("KadFindBuddyRes %s")) % Uint32_16toStringIP_Port(wxUINT32_SWAP_ALWAYS(ip), port)); sendPacket(&bio2, KADEMLIA_FINDBUDDY_RES, ip, port);}//KADEMLIA_FINDBUDDY_RESvoid CKademliaUDPListener::processFindBuddyResponse (const byte *packetData, uint32 lenPacket, uint32 ip, uint16 port){ // Verify packet is expected size if (lenPacket < 34) { throw wxString::Format(wxT("***NOTE: Received wrong size (%u) packet in "), lenPacket) + wxString::FromAscii(__FUNCTION__); } CMemFile bio((byte*)packetData, lenPacket); CUInt128 check = bio.ReadUInt128(); check.XOR(CUInt128(true)); if( CKademlia::getPrefs()->getKadID().compareTo(check)) { return; } CUInt128 userID = bio.ReadUInt128(); uint16 tcpport = bio.ReadUInt16(); CContact contact; contact.setIPAddress(ip); contact.setTCPPort(tcpport); contact.setUDPPort(port); contact.setClientID(userID); theApp.clientlist->RequestBuddy(&contact);}//KADEMLIA_CALLBACK_REQvoid CKademliaUDPListener::processCallbackRequest (const byte *packetData, uint32 lenPacket, uint32 ip, uint16 port){ // Verify packet is expected size if (lenPacket < 34) { throw wxString::Format(wxT("***NOTE: Received wrong size (%u) packet in "), lenPacket) + wxString::FromAscii(__FUNCTION__); } CUpDownClient* buddy = theApp.clientlist->GetBuddy(); if( buddy != NULL ) { CMemFile bio((byte*)packetData, lenPacket); CUInt128 check = bio.ReadUInt128(); // JOHNTODO: Filter bad buddies //CUInt128 bud(buddy->GetBuddyID()); CUInt128 file = bio.ReadUInt128(); uint16 tcp = bio.ReadUInt16(); CMemFile bio2(lenPacket+6); bio2.WriteUInt128(check); bio2.WriteUInt128(file); bio2.WriteUInt32(ip); bio2.WriteUInt16(tcp); CPacket* packet = new CPacket(&bio2, OP_EMULEPROT, OP_CALLBACK); if( buddy->GetSocket() ) { AddDebugLogLineM(false, logClientKadUDP, CFormat(wxT("KadCallback %s")) % Uint32_16toStringIP_Port(wxUINT32_SWAP_ALWAYS(ip), port)); theStats::AddUpOverheadFileRequest(packet->GetPacketSize()); buddy->GetSocket()->SendPacket(packet); } else { wxASSERT(0); } }}void CKademliaUDPListener::sendPacket(const byte *data, uint32 lenData, uint32 destinationHost, uint16 destinationPort){ //This is temp.. The entire Kad code will be rewritten using CMemFile and send a Packet object directly. CMemFile mem_data((byte*)data+2,lenData-2); sendPacket(&mem_data,data[1],destinationHost, destinationPort);}void CKademliaUDPListener::sendPacket(const byte *data, uint32 lenData, byte opcode, uint32 destinationHost, uint16 destinationPort){ CMemFile mem_data((byte*)data,lenData); sendPacket(&mem_data,opcode,destinationHost, destinationPort);}void CKademliaUDPListener::sendPacket(CMemFile *data, byte opcode, uint32 destinationHost, uint16 destinationPort){ CPacket* packet = new CPacket(data, OP_KADEMLIAHEADER, opcode); if( packet->GetPacketSize() > 200 ) { packet->PackPacket(); } theStats::AddUpOverheadKad(packet->GetPacketSize()); theApp.clientudp->SendPacket(packet,wxUINT32_SWAP_ALWAYS(destinationHost), destinationPort);}void CKademliaUDPListener::DebugClientOutput(const wxString& place, uint32 ip, uint32 port) { printf("Error on %s received from: %s\n",(const char*)unicode2char(place),(const char*)unicode2char(Uint32_16toStringIP_Port(ip,port))); CClientList::SourceList clientslist = theApp.clientlist->GetClientsByIP(ip); if (!clientslist.empty()) { for (CClientList::SourceList::iterator it = clientslist.begin(); it != clientslist.end(); ++it) { printf("Ip Matches: %s\n",(const char*)unicode2char((*it)->GetClientFullInfo())); } } else { printf("No ip match\n"); }}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?