kademliaudplistener.cpp
来自「wxWidgets写的电驴」· C++ 代码 · 共 1,226 行 · 第 1/3 页
CPP
1,226 行
//This makes sure we are not mistaken identify. Some client may have fresh installed and have a new hash. CUInt128 check = bio.ReadUInt128(); if( CKademlia::getPrefs()->getKadID().compareTo(check)) { return; } // Get required number closest to target ContactMap results; CKademlia::getRoutingZone()->getClosestTo(2, target, distance, (int)type, &results); uint16 count = (uint16)results.size(); // Write response // Max count is 32. size 817.. // 16 + 1 + 25(32) CMemFile bio2( 817 ); bio2.WriteUInt128(target); bio2.WriteUInt8((byte)count); CContact *c; ContactMap::const_iterator it; for (it = results.begin(); it != results.end(); it++) { c = it->second; bio2.WriteUInt128(c->getClientID()); bio2.WriteUInt32(c->getIPAddress()); bio2.WriteUInt16(c->getUDPPort()); bio2.WriteUInt16(c->getTCPPort()); bio2.WriteUInt8(c->getType()); } AddDebugLogLineM(false, logClientKadUDP, CFormat(wxT("KadRes %s Count=%u")) % Uint32_16toStringIP_Port(wxUINT32_SWAP_ALWAYS(ip), port) % count); sendPacket(&bio2, KADEMLIA_RES, ip, port);}//KADEMLIA_RESvoid CKademliaUDPListener::processKademliaResponse (const byte *packetData, uint32 lenPacket, uint32 ip, uint16 port){ // Verify packet is expected size if (lenPacket < 17){ throw wxString::Format(wxT("***NOTE: Received wrong size (%u) packet in "), lenPacket) + wxString::FromAscii(__FUNCTION__); } //Used Pointers CRoutingZone *routingZone = CKademlia::getRoutingZone(); if(CKademlia::getPrefs()->getRecheckIP()) { firewalledCheck(ip, port); AddDebugLogLineM(false, logClientKadUDP, CFormat(wxT("KadHelloReq %s")) % Uint32_16toStringIP_Port(wxUINT32_SWAP_ALWAYS(ip), port)); sendMyDetails(KADEMLIA_HELLO_REQ, ip, port); } // What search does this relate to CMemFile bio((byte*)packetData, lenPacket); CUInt128 target = bio.ReadUInt128(); uint16 numContacts = bio.ReadUInt8(); // Verify packet is expected size if (lenPacket != (uint32)(16+1 + (16+4+2+2+1)*numContacts)) { throw wxString::Format(wxT("***NOTE: Received wrong size (%u) packet in "), lenPacket) + wxString::FromAscii(__FUNCTION__); } // Set contact to alive. routingZone->setAlive(ip, port); ContactList *results = new ContactList; try { for (uint16 i=0; i<numContacts; i++) { CUInt128 id = bio.ReadUInt128(); uint32 contactIP = bio.ReadUInt32(); uint16 contactPort = bio.ReadUInt16(); uint16 tport = bio.ReadUInt16(); byte type = bio.ReadUInt8(); if(::IsGoodIPPort(wxUINT32_SWAP_ALWAYS(contactIP),contactPort)) { routingZone->add(id, contactIP, contactPort, tport, type); results->push_back(new CContact(id, contactIP, contactPort, tport, target)); } } } catch(...) { delete results; throw; } CSearchManager::processResponse(target, ip, port, results);}void CKademliaUDPListener::Free(SSearchTerm* pSearchTerms){ if (!pSearchTerms) { return; } Free(pSearchTerms->left); Free(pSearchTerms->right); delete pSearchTerms;}SSearchTerm* CKademliaUDPListener::CreateSearchExpressionTree(CMemFile& bio, int iLevel){ // the max. depth has to match our own limit for creating the search expression // (see also 'ParsedSearchExpression' and 'GetSearchPacket') if (iLevel >= 24){ AddDebugLogLineM(false, logClientKadUDP, wxT("***NOTE: Search expression tree exceeds depth limit!")); return NULL; } iLevel++; uint8 op = bio.ReadUInt8(); if (op == 0x00) { uint8 boolop = bio.ReadUInt8(); if (boolop == 0x00) { // AND SSearchTerm* pSearchTerm = new SSearchTerm; pSearchTerm->type = SSearchTerm::AND; //TRACE(" AND"); if ((pSearchTerm->left = CreateSearchExpressionTree(bio, iLevel)) == NULL){ wxASSERT(0); delete pSearchTerm; return NULL; } if ((pSearchTerm->right = CreateSearchExpressionTree(bio, iLevel)) == NULL){ wxASSERT(0); Free(pSearchTerm->left); delete pSearchTerm; return NULL; } return pSearchTerm; } else if (boolop == 0x01) { // OR SSearchTerm* pSearchTerm = new SSearchTerm; pSearchTerm->type = SSearchTerm::OR; //TRACE(" OR"); if ((pSearchTerm->left = CreateSearchExpressionTree(bio, iLevel)) == NULL){ wxASSERT(0); delete pSearchTerm; return NULL; } if ((pSearchTerm->right = CreateSearchExpressionTree(bio, iLevel)) == NULL){ wxASSERT(0); Free(pSearchTerm->left); delete pSearchTerm; return NULL; } return pSearchTerm; } else if (boolop == 0x02) { // NAND SSearchTerm* pSearchTerm = new SSearchTerm; pSearchTerm->type = SSearchTerm::NAND; //TRACE(" NAND"); if ((pSearchTerm->left = CreateSearchExpressionTree(bio, iLevel)) == NULL){ wxASSERT(0); delete pSearchTerm; return NULL; } if ((pSearchTerm->right = CreateSearchExpressionTree(bio, iLevel)) == NULL){ wxASSERT(0); Free(pSearchTerm->left); delete pSearchTerm; return NULL; } return pSearchTerm; } else{ AddDebugLogLineM(false, logKadSearch, wxString::Format(wxT("*** Unknown boolean search operator 0x%02x (CreateSearchExpressionTree)"), boolop)); return NULL; } } else if (op == 0x01) { // String CTagValueString str(bio.ReadString(true)); KadTagStrMakeLower(str); // make lowercase, the search code expects lower case strings! //TRACE(" \"%ls\"", str); SSearchTerm* pSearchTerm = new SSearchTerm; pSearchTerm->type = SSearchTerm::String; pSearchTerm->astr = new wxArrayString; // pre-tokenize the string term wxStringTokenizer token(str,InvKadKeywordChars,wxTOKEN_DEFAULT ); while (token.HasMoreTokens()) { CTagValueString strTok(token.GetNextToken()); if (!strTok.IsEmpty()) { pSearchTerm->astr->Add(strTok); } } return pSearchTerm; } else if (op == 0x02) { // Meta tag // read tag value CTagValueString strValue(bio.ReadString(true)); KadTagStrMakeLower(strValue); // make lowercase, the search code expects lower case strings! // read tag name wxString strTagName = bio.ReadString(true); SSearchTerm* pSearchTerm = new SSearchTerm; pSearchTerm->type = SSearchTerm::MetaTag; pSearchTerm->tag = new Kademlia::CTagStr(strTagName, strValue); return pSearchTerm; } else if (op == 0x03) { // Min/Max static const struct { SSearchTerm::ESearchTermType eSearchTermOp; wxString pszOp; } _aOps[] = { { SSearchTerm::OpEqual, wxT("=") }, // mmop=0x00 { SSearchTerm::OpGreaterEqual, wxT(">=") }, // mmop=0x01 { SSearchTerm::OpLessEqual, wxT("<=") }, // mmop=0x02 { SSearchTerm::OpGreater, wxT(">") }, // mmop=0x03 { SSearchTerm::OpLess, wxT("<") }, // mmop=0x04 { SSearchTerm::OpNotEqual, wxT("!=") } // mmop=0x05 }; // read tag value uint32 uValue = bio.ReadUInt32(); // read integer operator uint8 mmop = bio.ReadUInt8(); if (mmop >= ARRSIZE(_aOps)){ AddDebugLogLineM(false, logClientKadUDP, wxString::Format(wxT("*** Unknown integer search op=0x%02x (CreateSearchExpressionTree)"), mmop)); return NULL; } // read tag name wxString strTagName = bio.ReadString(false); SSearchTerm* pSearchTerm = new SSearchTerm; pSearchTerm->type = _aOps[mmop].eSearchTermOp; pSearchTerm->tag = new Kademlia::CTagUInt32(strTagName, uValue); return pSearchTerm; } else{ AddDebugLogLineM(false, logClientKadUDP, wxString::Format(wxT("*** Unknown search op=0x%02x (CreateSearchExpressionTree)"), op)); return NULL; }}//KADEMLIA_SEARCH_REQvoid CKademliaUDPListener::processSearchRequest (const byte *packetData, uint32 lenPacket, uint32 ip, uint16 port){ // Verify packet is expected size if (lenPacket < 17){ throw wxString::Format(wxT("***NOTE: Received wrong size (%u) packet in "), lenPacket) + wxString::FromAscii(__FUNCTION__); } CMemFile bio((byte*)packetData, lenPacket); CUInt128 target = bio.ReadUInt128(); uint8 restrictive = bio.ReadUInt8();#ifdef _DEBUG //DWORD dwNow = GetTickCount();#endif if(lenPacket == 17 ) { if(restrictive) { //Source request CKademlia::getIndexed()->SendValidSourceResult(target, ip, port); //DEBUG_ONLY( Debug("SendValidSourceResult: Time=%.2f sec\n", (GetTickCount() - dwNow) / 1000.0) ); } else { //Single keyword request CKademlia::getIndexed()->SendValidKeywordResult(target, NULL, ip, port ); //DEBUG_ONLY( Debug("SendValidKeywordResult (Single): Time=%.2f sec\n", (GetTickCount() - dwNow) / 1000.0) ); } } else if(lenPacket > 17) { SSearchTerm* pSearchTerms = NULL; if (restrictive) { try { pSearchTerms = CreateSearchExpressionTree(bio, 0); //TRACE("\n"); } catch(...) { Free(pSearchTerms); throw; } } //Keyword request with added options. CKademlia::getIndexed()->SendValidKeywordResult(target, pSearchTerms, ip, port); Free(pSearchTerms); //DEBUG_ONLY( Debug("SendValidKeywordResult: Time=%.2f sec\n", (GetTickCount() - dwNow) / 1000.0) ); }}//KADEMLIA_SEARCH_RESvoid CKademliaUDPListener::processSearchResponse (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); // How many results.. Not supported yet.. 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::processSearchResponse"),ip,port); deleteTagListEntries(tags); delete tags; tags = NULL; throw; } CSearchManager::processResult(target, ip, port, answer, tags); count--; }}//KADEMLIA_PUBLISH_REQvoid CKademliaUDPListener::processPublishRequest (const byte *packetData, uint32 lenPacket, uint32 ip, uint16 port){ //There are different types of publishing.. //Keyword and File are Stored.. // Verify packet is expected size if (lenPacket < 37) { throw wxString::Format(wxT("***NOTE: Received wrong size (%u) packet in "), lenPacket) + wxString::FromAscii(__FUNCTION__); } //Used Pointers CIndexed *indexed = CKademlia::getIndexed(); 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 file; bio.readUInt128(&file); CUInt128 distance(CKademlia::getPrefs()->getKadID()); distance.XOR(file); if( thePrefs::FilterLanIPs() && distance.get32BitChunk(0) > SEARCHTOLERANCE) { return; } wxString strInfo; uint16 count = bio.readUInt16(); bool flag = false; uint8 load = 0; while( count > 0 ) { strInfo.Clear(); CUInt128 target; bio.readUInt128(&target); Kademlia::CEntry* entry = new Kademlia::CEntry(); try { entry->ip = ip; entry->udpport = port; entry->keyID.setValue(file); entry->sourceID.setValue(target); uint32 tags = bio.readByte(); while(tags > 0) { CTag* tag = bio.readTag(); if(tag) { if (!tag->m_name.Cmp(wxT(TAG_SOURCETYPE)) && tag->m_type == 9) { if( entry->source == false ) { entry->taglist.push_back(new CTagUInt32(TAG_SOURCEIP, entry->ip)); entry->taglist.push_back(new CTagUInt16(TAG_SOURCEUPORT, entry->udpport)); } else { //More than one sourcetype tag found. delete tag; } entry->source = true; } if (!tag->m_name.Cmp(wxT(TAG_FILENAME))) { if ( entry->fileName.IsEmpty() ) { entry->fileName = tag->GetStr(); KadTagStrMakeLower(entry->fileName); // make lowercase, the search code expects lower case strings! strInfo += CFormat(wxT(" Name=\"%s\"")) % entry->fileName; // NOTE: always add the 'name' tag, even if it's stored separately in 'fileName'. the tag is still needed for answering search request entry->taglist.push_back(tag); } else { //More then one Name tag found. delete tag; } } else if (!tag->m_name.Cmp(wxT(TAG_FILESIZE))) { if( entry->size == 0 ) { entry->size = tag->GetInt(); strInfo += wxString::Format(wxT(" Size=%u"), entry->size); // NOTE: always add the 'size' tag, even if it's stored separately in 'size'. the tag is still needed for answering search request entry->taglist.push_back(tag); } else { //More then one size tag found delete tag; } } else if (!tag->m_name.Cmp(wxT(TAG_SOURCEPORT))) { if( entry->tcpport == 0 ) { entry->tcpport = tag->GetInt(); entry->taglist.push_back(tag); } else { //More then one port tag found delete tag; }
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?