📄 kademliaudplistener.cpp
字号:
// the max. depth has to match our own limit for creating the search expression // (see also 'ParsedSearchExpression' and 'GetSearchPacket') if (iLevel >= 24){ AddDebugLogLineM(false, logKadSearch, wxT("***NOTE: Search expression tree exceeds depth limit!")); return NULL; } iLevel++; uint8_t op = bio.ReadUInt8(); if (op == 0x00) { uint8_t boolop = bio.ReadUInt8(); if (boolop == 0x00) { // AND SSearchTerm* pSearchTerm = new SSearchTerm; pSearchTerm->type = SSearchTerm::AND; //TRACE(" AND"); if ((pSearchTerm->left = CreateSearchExpressionTree(bio, iLevel)) == NULL){ wxFAIL; delete pSearchTerm; return NULL; } if ((pSearchTerm->right = CreateSearchExpressionTree(bio, iLevel)) == NULL){ wxFAIL; 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){ wxFAIL; delete pSearchTerm; return NULL; } if ((pSearchTerm->right = CreateSearchExpressionTree(bio, iLevel)) == NULL){ wxFAIL; Free(pSearchTerm->left); delete pSearchTerm; return NULL; } return pSearchTerm; } else if (boolop == 0x02) { // NOT SSearchTerm* pSearchTerm = new SSearchTerm; pSearchTerm->type = SSearchTerm::NOT; //TRACE(" NOT"); if ((pSearchTerm->left = CreateSearchExpressionTree(bio, iLevel)) == NULL){ wxFAIL; delete pSearchTerm; return NULL; } if ((pSearchTerm->right = CreateSearchExpressionTree(bio, iLevel)) == NULL){ wxFAIL; 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 wxString str(bio.ReadString(true)); // Make lowercase, the search code expects lower case strings! str.MakeLower(); SSearchTerm* pSearchTerm = new SSearchTerm; pSearchTerm->type = SSearchTerm::String; pSearchTerm->astr = new wxArrayString; // pre-tokenize the string term //#warning TODO: TokenizeOptQuotedSearchTerm wxStringTokenizer token(str, CSearchManager::GetInvalidKeywordChars(),wxTOKEN_DEFAULT ); while (token.HasMoreTokens()) { wxString strTok(token.GetNextToken()); if (!strTok.IsEmpty()) { pSearchTerm->astr->Add(strTok); } } return pSearchTerm; } else if (op == 0x02) { // Meta tag // read tag value wxString strValue(bio.ReadString(true)); // Make lowercase, the search code expects lower case strings! strValue.MakeLower(); // read tag name wxString strTagName = bio.ReadString(false); SSearchTerm* pSearchTerm = new SSearchTerm; pSearchTerm->type = SSearchTerm::MetaTag; pSearchTerm->tag = new CTagString(strTagName, strValue); return pSearchTerm; } else if (op == 0x03 || op == 0x08) { // Numeric relation (0x03=32-bit or 0x08=64-bit) static const struct { SSearchTerm::ESearchTermType eSearchTermOp; wxString pszOp; } _aOps[] = { { SSearchTerm::OpEqual, wxT("=") }, // mmop=0x00 { SSearchTerm::OpGreater, wxT(">") }, // mmop=0x01 { SSearchTerm::OpLess, wxT("<") }, // mmop=0x02 { SSearchTerm::OpGreaterEqual, wxT(">=") }, // mmop=0x03 { SSearchTerm::OpLessEqual, wxT("<=") }, // mmop=0x04 { SSearchTerm::OpNotEqual, wxT("<>") } // mmop=0x05 }; // read tag value uint64_t ullValue = (op == 0x03) ? bio.ReadUInt32() : bio.ReadUInt64(); // read integer operator uint8_t mmop = bio.ReadUInt8(); if (mmop >= itemsof(_aOps)){ AddDebugLogLineM(false, logKadSearch, 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 CTagVarInt(strTagName, ullValue); return pSearchTerm; } else { AddDebugLogLineM(false, logKadSearch, wxString::Format(wxT("*** Unknown search op=0x%02x (CreateSearchExpressionTree)"), op)); return NULL; }}// KADEMLIA_SEARCH_REQ// Used in Kad1.0 onlyvoid CKademliaUDPListener::ProcessSearchRequest(const uint8_t *packetData, uint32_t lenPacket, uint32_t ip, uint16_t port){ // Verify packet is expected size CHECK_PACKET_MIN_SIZE(17); CMemFile bio(packetData, lenPacket); CUInt128 target = bio.ReadUInt128(); uint8_t restrictive = bio.ReadUInt8(); if (lenPacket == 17) { if (restrictive) { // Source request CKademlia::GetIndexed()->SendValidSourceResult(target, ip, port, false, 0, 0, 0); } else { // Single keyword request CKademlia::GetIndexed()->SendValidKeywordResult(target, NULL, ip, port, true, false, 0, 0); } } else if (lenPacket > 17) { SSearchTerm* pSearchTerms = NULL; bool oldClient = true; if (restrictive) { pSearchTerms = CreateSearchExpressionTree(bio, 0); if (pSearchTerms == NULL) { throw wxString(wxT("Invalid search expression")); } if (restrictive > 1) { oldClient = false; } } else { oldClient = false; } // Keyword request with added options. CKademlia::GetIndexed()->SendValidKeywordResult(target, pSearchTerms, ip, port, oldClient, false, 0, 0); Free(pSearchTerms); }}// KADEMLIA2_SEARCH_KEY_REQ// Used in Kad2.0 onlyvoid CKademliaUDPListener::Process2SearchKeyRequest(const uint8_t *packetData, uint32_t lenPacket, uint32_t ip, uint16_t port, const CKadUDPKey& senderKey){ CMemFile bio(packetData, lenPacket); CUInt128 target = bio.ReadUInt128(); uint16_t startPosition = bio.ReadUInt16(); bool restrictive = ((startPosition & 0x8000) == 0x8000); startPosition &= 0x7FFF; SSearchTerm* pSearchTerms = NULL; if (restrictive) { pSearchTerms = CreateSearchExpressionTree(bio, 0); if (pSearchTerms == NULL) { throw wxString(wxT("Invalid search expression")); } } CKademlia::GetIndexed()->SendValidKeywordResult(target, pSearchTerms, ip, port, false, true, startPosition, senderKey); if (pSearchTerms) { Free(pSearchTerms); }}// KADEMLIA2_SEARCH_SOURCE_REQ// Used in Kad2.0 onlyvoid CKademliaUDPListener::Process2SearchSourceRequest(const uint8_t *packetData, uint32_t lenPacket, uint32_t ip, uint16_t port, const CKadUDPKey& senderKey){ CMemFile bio(packetData, lenPacket); CUInt128 target = bio.ReadUInt128(); uint16_t startPosition = (bio.ReadUInt16() & 0x7FFF); uint64_t fileSize = bio.ReadUInt64(); CKademlia::GetIndexed()->SendValidSourceResult(target, ip, port, true, startPosition, fileSize, senderKey);}// KADEMLIA_SEARCH_RES// Used in Kad1.0 onlyvoid CKademliaUDPListener::ProcessSearchResponse(const uint8_t *packetData, uint32_t lenPacket){ // Verify packet is expected size CHECK_PACKET_MIN_SIZE(37); // What search does this relate to CMemFile bio(packetData, lenPacket); CUInt128 target = bio.ReadUInt128(); // How many results.. Not supported yet.. uint16_t count = bio.ReadUInt16(); while (count > 0) { // What is the answer CUInt128 answer = bio.ReadUInt128(); // 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! TagPtrList* tags = new TagPtrList; try { bio.ReadTagPtrList(tags, true/*bOptACP*/); } catch(...) { //DebugClientOutput(wxT("CKademliaUDPListener::processSearchResponse"),ip,port,packetData,lenPacket); deleteTagPtrListEntries(tags); delete tags; tags = NULL; throw; } CSearchManager::ProcessResult(target, answer, tags); count--; }}// KADEMLIA2_SEARCH_RES// Used in Kad2.0 onlyvoid CKademliaUDPListener::Process2SearchResponse(const uint8_t *packetData, uint32_t lenPacket, const CKadUDPKey& WXUNUSED(senderKey)){ CMemFile bio(packetData, lenPacket); // Who sent this packet. CUInt128 source = bio.ReadUInt128(); // What search does this relate to CUInt128 target = bio.ReadUInt128(); // Total results. uint16_t count = bio.ReadUInt16(); while (count > 0) { // What is the answer CUInt128 answer = bio.ReadUInt128(); // 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! TagPtrList* tags = new TagPtrList; try { bio.ReadTagPtrList(tags, true); } catch(...) { deleteTagPtrListEntries(tags); delete tags; tags = NULL; throw; } CSearchManager::ProcessResult(target, answer, tags); count--; }}// KADEMLIA_PUBLISH_REQ// Used in Kad1.0 onlyvoid CKademliaUDPListener::ProcessPublishRequest(const uint8_t *packetData, uint32_t lenPacket, uint32_t ip, uint16_t port){ //There are different types of publishing.. //Keyword and File are Stored.. // Verify packet is expected size CHECK_PACKET_MIN_SIZE(37); //Used Pointers CIndexed *indexed = CKademlia::GetIndexed(); // check if we are UDP firewalled if (CUDPFirewallTester::IsFirewalledUDP(true)) { //We are firewalled. We should not index this entry and give publisher a false report. return; } CMemFile bio(packetData, lenPacket); CUInt128 file = bio.ReadUInt128(); CUInt128 distance(CKademlia::GetPrefs()->GetKadID()); distance.XOR(file); if (thePrefs::FilterLanIPs() && distance.Get32BitChunk(0) > SEARCHTOLERANCE) { return; } wxString strInfo; uint16_t count = bio.ReadUInt16(); bool flag = false; uint8_t load = 0; while (count > 0) { strInfo.Clear(); CUInt128 target = bio.ReadUInt128(); Kademlia::CKeyEntry* entry = new Kademlia::CKeyEntry(); try { entry->m_uIP = ip; entry->m_uUDPport = port; entry->m_uKeyID.SetValue(file); entry->m_uSourceID.SetValue(target); uint32_t tags = bio.ReadUInt8(); while (tags > 0) { CTag* tag = bio.ReadTag(); if (tag) { if (!tag->GetName().Cmp(TAG_SOURCETYPE)) { if (entry->m_bSource == false) { entry->AddTag(new CTagVarInt(TAG_SOURCEIP, entry->m_uIP)); entry->AddTag(new CTagVarInt(TAG_SOURCEUPORT, entry->m_uUDPport)); entry->AddTag(tag); entry->m_bSource = true; } else { //More than one sourcetype tag found. delete tag; } } else if (!tag->GetName().Cmp(TAG_FILENAME)) { if (entry->GetCommonFileName().IsEmpty()) { entry->SetFileName(tag->GetStr()); strInfo += CFormat(wxT(" Name=\"%s\"")) % tag->GetStr(); } delete tag; } else if (!tag->GetName().Cmp(TAG_FILESIZE)) { if (entry->m_uSize == 0) { if (tag->IsBsob() && (tag->GetBsobSize() == 8)) { // Kad1.0 uint64 type using a BSOB. entry->m_uSize = PeekUInt64(tag->GetBsob()); } else { wxASSERT(tag->IsInt()); entry->m_uSize = tag->GetInt(); } strInfo += wxString::Format(wxT(" Size=%") wxLongLongFmtSpec wxT("u"), entry->m_uSize); } delete tag; } else if (!tag->GetName().Cmp(TAG_SOURCEPORT)) { if (entry->m_uTCPport == 0) { entry->m_uTCPport = tag->GetInt(); entry->AddTag(tag);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -