📄 kademliaudplistener.cpp
字号:
}
}
//KADEMLIA_SEARCH_REQ
void CKademliaUDPListener::processSearchRequest (const byte *packetData, uint32 lenPacket, uint32 ip, uint16 port)
{
// Verify packet is expected size
if (lenPacket < 17){
CString strError;
strError.Format("***NOTE: Received wrong size (%u) packet in %s", lenPacket, __FUNCTION__);
throw strError;
}
//Used Pointers
CIndexed *indexed = CKademlia::getIndexed();
ASSERT(indexed != NULL);
CSafeMemFile bio( packetData, lenPacket);
CUInt128 target;
bio.ReadUInt128(&target);
uint8 restrictive = bio.ReadUInt8();
#ifdef _DEBUG
DWORD dwNow = GetTickCount();
#endif
if(lenPacket == 17 )
{
if(restrictive)
{
//Source request
indexed->SendValidSourceResult(target, ip, port);
//DEBUG_ONLY( Debug("SendValidSourceResult: Time=%.2f sec\n", (GetTickCount() - dwNow) / 1000.0) );
}
else
{
//Single keyword request
indexed->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.
indexed->SendValidKeywordResult(target, pSearchTerms, ip, port);
Free(pSearchTerms);
//DEBUG_ONLY( Debug("SendValidKeywordResult: Time=%.2f sec\n", (GetTickCount() - dwNow) / 1000.0) );
}
}
//KADEMLIA_SEARCH_RES
void CKademliaUDPListener::processSearchResponse (const byte *packetData, uint32 lenPacket, uint32 ip, uint16 port)
{
// Verify packet is expected size
if (lenPacket < 37){
CString strError;
strError.Format("***NOTE: Received wrong size (%u) packet in %s", lenPacket, __FUNCTION__);
throw strError;
}
//Used Pointers
CRoutingZone *routingZone = CKademlia::getRoutingZone();
ASSERT(routingZone != NULL);
// Set contact to alive.
routingZone->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
TagList *tags = bio.readTagList();
CSearchManager::processResult(target, ip, port, answer,tags);
count--;
}
}
//KADEMLIA_PUBLISH_REQ
void 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){
CString strError;
strError.Format("***NOTE: Received wrong size (%u) packet in %s", lenPacket, __FUNCTION__);
throw strError;
}
//Used Pointers
CIndexed *indexed = CKademlia::getIndexed();
ASSERT(indexed != NULL);
CPrefs *prefs = CKademlia::getPrefs();
ASSERT(prefs != NULL);
CByteIO bio(packetData, lenPacket);
CUInt128 file;
bio.readUInt128(&file);
CUInt128 distance;
prefs->getClientID(&distance);
distance.xor(file);
if( thePrefs.FilterLANIPs() && distance.get32BitChunk(0) > SEARCHTOLERANCE)
return;
bool bDbgInfo = thePrefs.GetDebugClientKadUDPLevel() > 0;
CString strInfo;
//TODO: Most li
uint16 count = bio.readUInt16();
bool flag = false;
while( count > 0 )
{
strInfo.Empty();
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.readUInt32LE();
uint32 tags = bio.readByte();
while(tags > 0)
{
CTag* tag = bio.readTag();
if (!tag->m_name.Compare(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));
}
entry->source = true;
}
if (!tag->m_name.Compare(TAG_NAME))
{
entry->fileName = tag->GetStr();
entry->fileName.MakeLower(); // make lowercase, the search code expects lower case strings!
if (bDbgInfo)
strInfo.AppendFormat(" 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 if (!tag->m_name.Compare(TAG_SIZE))
{
entry->size = tag->GetInt();
if (bDbgInfo)
strInfo.AppendFormat(" 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 if (!tag->m_name.Compare(TAG_SOURCEPORT))
{
entry->tcpport = tag->GetInt();
entry->taglist.push_back(tag);
}
else
{
//TODO: Filter tags
entry->taglist.push_back(tag);
}
tags--;
}
if (bDbgInfo && !strInfo.IsEmpty())
Debug("%s\n", strInfo);
}
catch(...)
{
delete entry;
throw;
}
if( entry->source == true )
{
if( indexed->AddSources(file, target, entry ) )
flag = true;
else
{
CKademlia::debugMsg("Source INDEX FULL %u (CKademliaUDPListener::processPublishRequest)", indexed->m_totalIndexSource);
delete entry;
entry = NULL;
}
}
else
{
if( entry->fileName.IsEmpty() || entry->size == 0 )
{
delete entry;
entry = NULL;
CKademlia::debugLine("Invalid entry CKademliaUDPListener::processPublishRequest");
}
else if( indexed->AddKeyword(file, target, entry, flag) )
{
//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 files for this keyword. Do not send a publish result so they index it to someone else.
// return;
}
}
count--;
}
if( flag )
{
CSafeMemFile bio2(16);
bio2.WriteUInt128(&file);
if (thePrefs.GetDebugClientKadUDPLevel() > 0)
DebugSend("KadPublishRes", ip, port);
sendPacket( &bio2, KADEMLIA_PUBLISH_RES, ip, port);
}
}
//KADEMLIA_PUBLISH_ACK
void CKademliaUDPListener::processPublishResponse (const byte *packetData, uint32 lenPacket, uint32 ip, uint16 port)
{
// Verify packet is expected size
if (lenPacket < 16){
CString strError;
strError.Format("***NOTE: Received wrong size (%u) packet in %s", lenPacket, __FUNCTION__);
throw strError;
}
//Used Pointers
CRoutingZone *routingZone = CKademlia::getRoutingZone();
ASSERT(routingZone != NULL);
// Set contact to alive.
routingZone->setAlive(ip, port);
CSafeMemFile bio(packetData, lenPacket);
CUInt128 file;
bio.ReadUInt128(&file);
CSearchManager::processPublishResult(file);
}
//KADEMLIA_FIREWALLED_REQ
void CKademliaUDPListener::processFirewalledRequest (const byte *packetData, uint32 lenPacket, uint32 ip, uint16 port)
{
// Verify packet is expected size
if (lenPacket != 2){
CString strError;
strError.Format("***NOTE: Received wrong size (%u) packet in %s", lenPacket, __FUNCTION__);
throw strError;
}
CSafeMemFile bio(packetData, lenPacket);
uint16 tcpport = bio.ReadUInt16();
CContact contact;
contact.setIPAddress(ip);
contact.setTCPPort(tcpport);
contact.setUDPPort(port);
theApp.clientlist->RequestTCP(&contact);
// Send response
CSafeMemFile bio2(4);
bio2.WriteUInt32(ip);
if (thePrefs.GetDebugClientKadUDPLevel() > 0)
DebugSend("KadFirewalledRes", ip, port);
sendPacket(&bio2, KADEMLIA_FIREWALLED_RES, ip, port);
}
//KADEMLIA_FIREWALLED_RES
void CKademliaUDPListener::processFirewalledResponse (const byte *packetData, uint32 lenPacket, uint32 ip, uint16 port)
{
// Verify packet is expected size
if (lenPacket != 4){
CString strError;
strError.Format("***NOTE: Received wrong size (%u) packet in %s", lenPacket, __FUNCTION__);
throw strError;
}
//Used Pointers
CRoutingZone *routingZone = CKademlia::getRoutingZone();
ASSERT(routingZone != NULL);
// Set contact to alive.
routingZone->setAlive(ip, port);
CSafeMemFile bio(packetData, lenPacket);
uint32 firewalledIP = bio.ReadUInt32();
CPrefs *prefs = CKademlia::getPrefs();
ASSERT(prefs != NULL);
//Update con state only if something changes.
if( prefs->getIPAddress() != firewalledIP )
{
prefs->setIPAddress(firewalledIP);
theApp.emuledlg->ShowConnectionState();
}
prefs->incRecheckIP();
}
//KADEMLIA_FIREWALLED_ACK
void CKademliaUDPListener::processFirewalledResponse2 (const byte *packetData, uint32 lenPacket, uint32 ip, uint16 port)
{
// Verify packet is expected size
if (lenPacket != 0){
CString strError;
strError.Format("***NOTE: Received wrong size (%u) packet in %s", lenPacket, __FUNCTION__);
throw strError;
}
//Used Pointers
CPrefs *prefs = CKademlia::getPrefs();
ASSERT(prefs != NULL);
CRoutingZone *routingZone = CKademlia::getRoutingZone();
ASSERT(routingZone != NULL);
// Set contact to alive.
routingZone->setAlive(ip, port);
prefs->incFirewalled();
}
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.
Packet* packet = new Packet(OP_KADEMLIAHEADER);
packet->opcode = data[1];
packet->pBuffer = new char[lenData+8];
memcpy(packet->pBuffer, data+2, lenData-2);
packet->size = lenData-2;
if( lenData > 200 )
packet->PackPacket();
theApp.uploadqueue->AddUpDataOverheadKad(packet->size);
theApp.clientudp->SendPacket(packet, ntohl(destinationHost), destinationPort);
}
void CKademliaUDPListener::sendPacket(const byte *data, uint32 lenData, byte opcode, uint32 destinationHost, uint16 destinationPort)
{
Packet* packet = new Packet(OP_KADEMLIAHEADER);
packet->opcode = opcode;
packet->pBuffer = new char[lenData];
memcpy(packet->pBuffer, data, lenData);
packet->size = lenData;
if( lenData > 200 )
packet->PackPacket();
theApp.uploadqueue->AddUpDataOverheadKad(packet->size);
theApp.clientudp->SendPacket(packet, ntohl(destinationHost), destinationPort);
}
void CKademliaUDPListener::sendPacket(CSafeMemFile *data, byte opcode, uint32 destinationHost, uint16 destinationPort)
{
Packet* packet = new Packet(data, OP_KADEMLIAHEADER);
packet->opcode = opcode;
if( packet->size > 200 )
packet->PackPacket();
theApp.uploadqueue->AddUpDataOverheadKad(packet->size);
theApp.clientudp->SendPacket(packet, ntohl(destinationHost), destinationPort);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -