bool CIndexed::SendStoreRequest(const CUInt128& uKeyID) { Load* pLoad; if(m_mapLoad.Lookup(CCKey(uKeyID.GetData()), pLoad)) { if(pLoad->uTime < (uint32)time(NULL)) { m_mapLoad.RemoveKey(CCKey(uKeyID.GetData())); m_uTotalIndexLoad--; delete pLoad; return true; } return false; } return true; }
bool CKadID::SetKey(CHolder<CPublicKey>& pKey, UINT eAlgorithm) { if(m_PublicKey) return m_PublicKey->GetSize() == pKey->GetSize() && memcmp(m_PublicKey->GetKey(), pKey->GetKey(), m_PublicKey->GetSize()) == 0; CUInt128 ID; MakeID(pKey, ID.GetData(), ID.GetSize(), eAlgorithm); if(CompareTo(ID) != 0) return false; m_PublicKey = pKey; return true; }
bool CIndexed::AddLoad(const CUInt128& uKeyID, uint32 uTime) { //This is needed for when you restart the client. if((uint32)time(NULL)>uTime) return false; Load* pLoad; if(m_mapLoad.Lookup(CCKey(uKeyID.GetData()), pLoad)) return false; pLoad = new Load(); pLoad->uKeyID.SetValue(uKeyID); pLoad->uTime = uTime; m_mapLoad.SetAt(CCKey(pLoad->uKeyID.GetData()), pLoad); m_uTotalIndexLoad++; return true; }
void CIndexed::SendValidKeywordResult(const CUInt128& uKeyID, const SSearchTerm* pSearchTerms, uint32 uIP, uint16 uPort, bool bOldClient, bool bKad2, uint16 uStartPosition) { KeyHash* pCurrKeyHash; if(m_mapKeyword.Lookup(CCKey(uKeyID.GetData()), pCurrKeyHash)) { byte byPacket[1024*50]; CByteIO byIO(byPacket,sizeof(byPacket)); byIO.WriteByte(OP_KADEMLIAHEADER); if(bKad2) { byIO.WriteByte(KADEMLIA2_SEARCH_RES); byIO.WriteUInt128(Kademlia::CKademlia::GetPrefs()->GetKadID()); } else byIO.WriteByte(KADEMLIA_SEARCH_RES); byIO.WriteUInt128(uKeyID); byIO.WriteUInt16(50); uint16 uMaxResults = 300; int iCount = 0-uStartPosition; POSITION pos1 = pCurrKeyHash->mapSource.GetStartPosition(); while( pos1 != NULL ) { CCKey key1; Source* pCurrSource; pCurrKeyHash->mapSource.GetNextAssoc( pos1, key1, pCurrSource ); for(POSITION pos2 = pCurrSource->ptrlEntryList.GetHeadPosition(); pos2 != NULL; ) { CEntry* pCurrName = pCurrSource->ptrlEntryList.GetNext(pos2); if ( !pSearchTerms || SearchTermsMatch(pSearchTerms, pCurrName) ) { if( iCount < 0 ) iCount++; else if( (uint16)iCount < uMaxResults ) { if((!bOldClient || pCurrName->m_uSize <= OLD_MAX_EMULE_FILE_SIZE)) { iCount++; byIO.WriteUInt128(pCurrName->m_uSourceID); byIO.WriteTagList(pCurrName->m_listTag); if( iCount % 50 == 0 ) { uint32 uLen = sizeof(byPacket)-byIO.GetAvailable(); CKademlia::GetUDPListener()->SendPacket(byPacket, uLen, uIP, uPort); byIO.Reset(); byIO.WriteByte(OP_KADEMLIAHEADER); if(bKad2) { if (thePrefs.GetDebugClientKadUDPLevel() > 0) DebugSend("KADEMLIA2_SEARCH_RES", uIP, uPort); byIO.WriteByte(KADEMLIA2_SEARCH_RES); byIO.WriteUInt128(Kademlia::CKademlia::GetPrefs()->GetKadID()); } else { if (thePrefs.GetDebugClientKadUDPLevel() > 0) DebugSend("KADEMLIA_SEARCH_RES", uIP, uPort); byIO.WriteByte(KADEMLIA_SEARCH_RES); } byIO.WriteUInt128(uKeyID); byIO.WriteUInt16(50); } } } else { pos1 = NULL; break; } } } } if(iCount > 0) { uint16 uCountLeft = (uint16)iCount % 50; if( uCountLeft ) { uint32 uLen = sizeof(byPacket)-byIO.GetAvailable(); if(bKad2) { memcpy(byPacket+18+16, &uCountLeft, 2); if (thePrefs.GetDebugClientKadUDPLevel() > 0) DebugSend("KADEMLIA2_SEARCH_RES", uIP, uPort); } else { memcpy(byPacket+18, &uCountLeft, 2); if (thePrefs.GetDebugClientKadUDPLevel() > 0) DebugSend("KADEMLIA_SEARCH_RES", uIP, uPort); } CKademlia::GetUDPListener()->SendPacket(byPacket, uLen, uIP, uPort); } } } Clean(); }
bool CIndexed::AddNotes(const CUInt128& uKeyID, const CUInt128& uSourceID, Kademlia::CEntry* pEntry, uint8& uLoad) { if( !pEntry ) return false; if( pEntry->m_uIP == 0 || pEntry->m_listTag.size() == 0 ) return false; SrcHash* pCurrNoteHash; if(!m_mapNotes.Lookup(CCKey(uKeyID.GetData()), pCurrNoteHash)) { Source* pCurrNote = new Source; pCurrNote->uSourceID.SetValue(uSourceID); pCurrNote->ptrlEntryList.AddHead(pEntry); SrcHash* pCurrNoteHash = new SrcHash; pCurrNoteHash->uKeyID.SetValue(uKeyID); pCurrNoteHash->ptrlistSource.AddHead(pCurrNote); m_mapNotes.SetAt(CCKey(pCurrNoteHash->uKeyID.GetData()), pCurrNoteHash); uLoad = 1; m_uTotalIndexNotes++; return true; } else { uint32 uSize = pCurrNoteHash->ptrlistSource.GetSize(); for(POSITION pos1 = pCurrNoteHash->ptrlistSource.GetHeadPosition(); pos1 != NULL; ) { Source* pCurrNote = pCurrNoteHash->ptrlistSource.GetNext(pos1); if( pCurrNote->ptrlEntryList.GetSize() ) { CEntry* pCurrEntry = pCurrNote->ptrlEntryList.GetHead(); if(pCurrEntry->m_uIP == pEntry->m_uIP || pCurrEntry->m_uSourceID == pEntry->m_uSourceID) { delete pCurrNote->ptrlEntryList.RemoveHead(); pCurrNote->ptrlEntryList.AddHead(pEntry); uLoad = (uint8)((uSize*100)/KADEMLIAMAXNOTESPERFILE); return true; } } else { //This should never happen! pCurrNote->ptrlEntryList.AddHead(pEntry); ASSERT(0); uLoad = (uint8)((uSize*100)/KADEMLIAMAXNOTESPERFILE); m_uTotalIndexKeyword++; return true; } } if( uSize > KADEMLIAMAXNOTESPERFILE ) { Source* pCurrNote = pCurrNoteHash->ptrlistSource.RemoveTail(); delete pCurrNote->ptrlEntryList.RemoveTail(); pCurrNote->uSourceID.SetValue(uSourceID); pCurrNote->ptrlEntryList.AddHead(pEntry); pCurrNoteHash->ptrlistSource.AddHead(pCurrNote); uLoad = 100; return true; } else { Source* pCurrNote = new Source; pCurrNote->uSourceID.SetValue(uSourceID); pCurrNote->ptrlEntryList.AddHead(pEntry); pCurrNoteHash->ptrlistSource.AddHead(pCurrNote); uLoad = (uint8)((uSize*100)/KADEMLIAMAXNOTESPERFILE); m_uTotalIndexKeyword++; return true; } } }
bool CIndexed::AddKeyword(const CUInt128& uKeyID, const CUInt128& uSourceID, Kademlia::CEntry* pEntry, uint8& uLoad) { if( !pEntry ) return false; if( m_uTotalIndexKeyword > KADEMLIAMAXENTRIES ) { uLoad = 100; return false; } if( pEntry->m_uSize == 0 || pEntry->m_fileName.IsEmpty() || pEntry->m_listTag.size() == 0 || pEntry->m_tLifetime < time(NULL)) return false; KeyHash* pCurrKeyHash; if(!m_mapKeyword.Lookup(CCKey(uKeyID.GetData()), pCurrKeyHash)) { Source* pCurrSource = new Source; pCurrSource->uSourceID.SetValue(uSourceID); pCurrSource->ptrlEntryList.AddHead(pEntry); pCurrKeyHash = new KeyHash; pCurrKeyHash->uKeyID.SetValue(uKeyID); pCurrKeyHash->mapSource.SetAt(CCKey(pCurrSource->uSourceID.GetData()), pCurrSource); m_mapKeyword.SetAt(CCKey(pCurrKeyHash->uKeyID.GetData()), pCurrKeyHash); uLoad = 1; m_uTotalIndexKeyword++; return true; } else { uint32 uIndexTotal = pCurrKeyHash->mapSource.GetCount(); if ( uIndexTotal > KADEMLIAMAXINDEX ) { uLoad = 100; //Too many entries for this Keyword.. return false; } Source* pCurrSource; if(pCurrKeyHash->mapSource.Lookup(CCKey(uSourceID.GetData()), pCurrSource)) { if (pCurrSource->ptrlEntryList.GetCount() > 0) { if( uIndexTotal > KADEMLIAMAXINDEX - 5000 ) { uLoad = 100; //We are in a hot node.. If we continued to update all the publishes //while this index is full, popular files will be the only thing you index. return false; } delete pCurrSource->ptrlEntryList.GetHead(); pCurrSource->ptrlEntryList.RemoveHead(); } else m_uTotalIndexKeyword++; uLoad = (uint8)((uIndexTotal*100)/KADEMLIAMAXINDEX); pCurrSource->ptrlEntryList.AddHead(pEntry); return true; } else { pCurrSource = new Source; pCurrSource->uSourceID.SetValue(uSourceID); pCurrSource->ptrlEntryList.AddHead(pEntry); pCurrKeyHash->mapSource.SetAt(CCKey(pCurrSource->uSourceID.GetData()), pCurrSource); m_uTotalIndexKeyword++; uLoad = (uint8)((uIndexTotal*100)/KADEMLIAMAXINDEX); return true; } } }
void CIndexed::SendValidNoteResult(const CUInt128& uKeyID, uint32 uIP, uint16 uPort, bool bKad2, uint64 uFileSize) { try { SrcHash* pCurrNoteHash; if(m_mapNotes.Lookup(CCKey(uKeyID.GetData()), pCurrNoteHash)) { byte byPacket[1024*50]; CByteIO byIO(byPacket,sizeof(byPacket)); byIO.WriteByte(OP_KADEMLIAHEADER); if(bKad2) { byIO.WriteByte(KADEMLIA2_SEARCH_RES); byIO.WriteUInt128(Kademlia::CKademlia::GetPrefs()->GetKadID()); } else byIO.WriteByte(KADEMLIA_SEARCH_NOTES_RES); byIO.WriteUInt128(uKeyID); byIO.WriteUInt16(50); uint16 uMaxResults = 150; uint16 uCount = 0; for(POSITION pos1 = pCurrNoteHash->ptrlistSource.GetHeadPosition(); pos1 != NULL; ) { Source* pCurrNote = pCurrNoteHash->ptrlistSource.GetNext(pos1); if( pCurrNote->ptrlEntryList.GetSize() ) { CEntry* pCurrName = pCurrNote->ptrlEntryList.GetHead(); if( uCount < uMaxResults ) { if( !uFileSize || !pCurrName->m_uSize || uFileSize == pCurrName->m_uSize ) { byIO.WriteUInt128(pCurrName->m_uSourceID); byIO.WriteTagList(pCurrName->m_listTag); uCount++; if( uCount % 50 == 0 ) { uint32 uLen = sizeof(byPacket)-byIO.GetAvailable(); CKademlia::GetUDPListener()->SendPacket(byPacket, uLen, uIP, uPort); byIO.Reset(); byIO.WriteByte(OP_KADEMLIAHEADER); if(bKad2) { if (thePrefs.GetDebugClientKadUDPLevel() > 0) DebugSend("KADEMLIA2_SEARCH_RES", uIP, uPort); byIO.WriteByte(KADEMLIA2_SEARCH_RES); byIO.WriteUInt128(Kademlia::CKademlia::GetPrefs()->GetKadID()); } else { if (thePrefs.GetDebugClientKadUDPLevel() > 0) DebugSend("KADEMLIA_SEARCH_NOTES_RES", uIP, uPort); byIO.WriteByte(KADEMLIA_SEARCH_NOTES_RES); } byIO.WriteUInt128(uKeyID); byIO.WriteUInt16(50); } } } else { break; } } } uint16 uCountLeft = uCount % 50; if( uCountLeft ) { uint32 uLen = sizeof(byPacket)-byIO.GetAvailable(); if(bKad2) { memcpy(byPacket+18+16, &uCountLeft, 2); if (thePrefs.GetDebugClientKadUDPLevel() > 0) DebugSend("KADEMLIA2_SEARCH_RES", uIP, uPort); } else { memcpy(byPacket+18, &uCountLeft, 2); if (thePrefs.GetDebugClientKadUDPLevel() > 0) DebugSend("KADEMLIA_SEARCH_NOTES_RES", uIP, uPort); } CKademlia::GetUDPListener()->SendPacket(byPacket, uLen, uIP, uPort); } } } catch(...) { AddDebugLogLine(false, _T("Exception in CIndexed::SendValidNoteResult")); } }
void CDataIO::WriteUInt128(const CUInt128& uVal) { WriteArray(uVal.GetData(), sizeof(uint32)*4); }
CKademlia::CKademlia(uint16 Port, bool bIPv6, const CVariant& Config, const string& Version) { m_Protocol = KAD_PROT_VER; if(!Version.empty()) m_Version += Version; else m_Version = "v " STR(KAD_PROT_MJR) "." STR(KAD_PROT_MIN); m_pConfig = new CKadConfig(this); if(Config.IsValid()) m_pConfig->Merge(Config); LoadData(); if(m_pKadKey->GetAlgorithm() == CAbstractKey::eUndefined) { m_pKadKey->SetAlgorithm(CAbstractKey::eECP); //m_pKadKey->GenerateKey("secp256r1"); // NIST: P-256 m_pKadKey->GenerateKey("brainpoolP256r1"); // dont trust NIST (NSA) curves, use brainpool LogLine(LOG_INFO, L"Generated new Private NodeKey"); SaveData(); } m_pSocket = new CSmartSocket(SEC2MS(Cfg()->GetInt("ConnectionTimeout")), this); CScoped<CPublicKey> pKey = m_pKadKey->PublicKey(); CUInt128 ID; CKadID::MakeID(pKey, ID.GetData(), ID.GetSize()); LogLine(LOG_INFO, L"Neo Kad ID: %s", ID.ToHex().c_str()); uint64 RecvKey; CAbstractKey::Fold(ID.GetData(), ID.GetSize(),(byte*)&RecvKey, sizeof(RecvKey)); m_pSocket->SetupCrypto(RecvKey, m_pKadKey); #ifdef _DEBUG LogLine(LOG_INFO, L"Socket PassKey is %I64u", RecvKey); #endif m_Port = 0; m_IPv4 = CAddress(CAddress::IPv4); m_IPv6 = CAddress(CAddress::IPv6); for(int i=Port; i < Port + 1000; i++) { CUTPSocketListner* pSocketListner = new CUTPSocketListner(m_pSocket); CUTPSocketListner* pSocketListnerV6 = bIPv6 ? new CUTPSocketListner(m_pSocket) : NULL; bool bV4 = pSocketListner->Bind(i, CAddress(CAddress::IPv4)); bool bV6 = !pSocketListnerV6 || pSocketListnerV6->Bind(i, CAddress(CAddress::IPv6)); if(bV4 && bV6) { m_pSocket->InstallListener(pSocketListner); if(pSocketListnerV6) m_pSocket->InstallListener(pSocketListnerV6); m_Port = i; break; } delete pSocketListner; delete pSocketListnerV6; } }