📄 kademliaudplistener.cpp
字号:
CRoutingZone *routingZone = CKademlia::getRoutingZone();
ASSERT(routingZone != NULL);
// Set contact to alive.
routingZone->setAlive(ntohl(senderAddress->sin_addr.s_addr), ntohs(senderAddress->sin_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,
ntohl(senderAddress->sin_addr.s_addr), ntohs(senderAddress->sin_port),
answer,
tags);
count = count - 1;
}
} catch (...) {TRACE("Exception in Kademlia Search Response\n");}
}
//KADEMLIA_PUBLISH_REQ
void CKademliaUDPListener::processPublishRequest (const byte *packetData, const uint32 lenPacket, const sockaddr_in *senderAddress)
{
//There are different types of publishing..
//Keyword and File are Stored..
try
{
if (lenPacket < 37){
ASSERT(0);
return;
}
//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);
CString dist;
distance.toBinaryString(&dist);
if(dist.Left(5) != "00000")
return;
// How many results.. Not supported yet..
uint16 count = bio.readUInt16();
while( count > 0 )
{
CUInt128 target;
bio.readUInt128(&target);
Kademlia::CEntry* entry = new Kademlia::CEntry();
entry->ip = ntohl(senderAddress->sin_addr.s_addr);
entry->udpport = ntohs(senderAddress->sin_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) // 9 means UInt8
{
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();
// 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();
// 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( !entry->source && (entry->fileName == "" || entry->size == 0 ))
{
delete entry;
TRACE("Invalid entry\n");
}
else
{
// add sourceip for keyword publish packet
if( !entry->source)
entry->taglist.push_back(new CTagUInt32(TAG_SOURCEIP, entry->ip));
indexed->IndexedAdd(file, target, entry);
}
count--;
}
// CKademlia::debugMsg("Sent UDP OpCode KADEMLIA_PUBLISH_RES (%u)", ntohl(senderAddress->sin_addr.s_addr));
byte response[18];
CByteIO bio2(response, sizeof(response));
bio2.writeByte(OP_KADEMLIAHEADER);
bio2.writeByte(KADEMLIA_PUBLISH_RES);
bio2.writeUInt128(file);
sendPacket(response, sizeof(response), ntohl(senderAddress->sin_addr.s_addr), ntohs(senderAddress->sin_port)) ;
} catch (...) {TRACE("Exception in Kademlia Publish Request\n");}
}
//KADEMLIA_PUBLISH_ACK
void CKademliaUDPListener::processPublishResponse (const byte *packetData, const uint32 lenPacket, const sockaddr_in *senderAddress)
{
try
{
if (lenPacket != 16){
ASSERT(0);
return;
}
//Used Pointers
CRoutingZone *routingZone = CKademlia::getRoutingZone();
ASSERT(routingZone != NULL);
// Set contact to alive.
routingZone->setAlive(ntohl(senderAddress->sin_addr.s_addr), ntohs(senderAddress->sin_port));
CByteIO bio(packetData, lenPacket);
CUInt128 file;
bio.readUInt128(&file);
CSearchManager::processPublishResult(file);
} catch (...) {TRACE("Exception in Kademlia Publish Response\n");}
}
//KADEMLIA_FIREWALLED_REQ
void CKademliaUDPListener::processFirewalledRequest (const byte *packetData, const uint32 lenPacket, const sockaddr_in *senderAddress)
{
try
{
if (lenPacket != 2 && lenPacket != 4){
ASSERT(0);
return;
}
CByteIO bio(packetData, lenPacket);
uint16 tcpport = bio.readUInt16();
uint16 udpport = ntohs(senderAddress->sin_port);
uint32 ip = ntohl(senderAddress->sin_addr.s_addr);
uint16 udpport2 = (lenPacket == 4 ? bio.readUInt16() : 0);
if(lenPacket == 4){
CContact* contact = new CContact();
contact->setIPAddress(ip);
contact->setTCPPort(tcpport);
contact->setUDPPort(udpport);
Kademlia::CKademlia::reportRequestTcp(contact);
}
// Send response
byte response[6];
CByteIO bio2(response, sizeof(response));
bio2.writeByte(OP_KADEMLIAHEADER);
bio2.writeByte(KADEMLIA_FIREWALLED_RES);
bio2.writeUInt32(ip);
// CKademlia::debugMsg("Sent UDP OpCode KADEMLIA_FIREWALLED_RES (%u)", ip);
sendPacket(response, sizeof(response), ip, udpport);
if(udpport2)
sendPacket(response, sizeof(response), ip, udpport2);
} catch (...) {TRACE("Exception in Kademlia Firewall Request\n");}
}
//KADEMLIA_FIREWALLED_RES
void CKademliaUDPListener::processFirewalledResponse (const byte *packetData, const uint32 lenPacket, const sockaddr_in *senderAddress)
{
try
{
if (lenPacket != 4){
ASSERT(0);
return;
}
//Used Pointers
CRoutingZone *routingZone = CKademlia::getRoutingZone();
ASSERT(routingZone != NULL);
// Set contact to alive.
routingZone->setAlive(ntohl(senderAddress->sin_addr.s_addr), ntohs(senderAddress->sin_port));
CByteIO bio(packetData, lenPacket);
uint32 ip = bio.readUInt32();
CPrefs *prefs = CKademlia::getPrefs();
ASSERT(prefs != NULL);
prefs->setIPAddress(ip);
CString ipStr;
CMiscUtils::ipAddressToString(ip, &ipStr);
} catch (...) {TRACE("Exception in Kademlia Firewall Response\n");}
}
//KADEMLIA_FIREWALLED_ACK
void CKademliaUDPListener::processFirewalledResponse2 (const byte *packetData, const uint32 lenPacket, const sockaddr_in *senderAddress)
{
try
{
if (lenPacket != 0){
ASSERT(0);
return;
}
//Used Pointers
CPrefs *prefs = CKademlia::getPrefs();
ASSERT(prefs != NULL);
CRoutingZone *routingZone = CKademlia::getRoutingZone();
ASSERT(routingZone != NULL);
// Set contact to alive.
routingZone->setAlive(ntohl(senderAddress->sin_addr.s_addr), ntohs(senderAddress->sin_port));
prefs->incFirewalled();
} catch (...) {TRACE("Exception in Kademlia Firewall Response2\n");}
}
void CKademliaUDPListener::processPartialRequest (const byte *packetData, const uint32 lenPacket, const sockaddr_in *senderAddress)
{
byte tth[24];
try
{
if (lenPacket < 27){ // 27 = sizeof(tth) + sizeof(tcpPort) + sizeof(count)
ASSERT(0);
return;
}
CByteIO bio(packetData, lenPacket);
uint16 tcpport = bio.readUInt16();
bio.readArray(tth, sizeof(tth));
uint8 cnt = bio.readUInt8();
uint32 lenExpect = (uint32)(27 + cnt * sizeof(unsigned short) * 2);
if(lenPacket < lenExpect){
ASSERT(0);
return;
}
const uint8* extension = NULL;
// Check extension length, if illegal, clear it
if(lenPacket > lenExpect){
uint32* lenExtension = (uint32*)(packetData + lenExpect);
if(lenPacket >= lenExpect + *lenExtension)
extension = packetData + lenExpect;
}
uint32 ip = ntohl(senderAddress->sin_addr.s_addr);
uint16 udpport = ntohs(senderAddress->sin_port);
uint8 cnt2 = 0xFF;
byte response[1500]; // TODO: buffer overrun
// Callback to get partical info
if(partialRequestHandler == NULL ||
!partialRequestHandler(ip, tcpport, udpport, tth, cnt, (uint16*)(packetData + 27), extension, &cnt2, (uint16*)(response + 29)))
return;
if(cnt2 == 0){
ASSERT(0);
return;
}
CPrefs *prefs = CKademlia::getPrefs();
ASSERT(prefs != NULL);
// Send response
CByteIO bio2(response, sizeof(response));
bio2.writeByte(OP_KADEMLIAHEADER);
bio2.writeByte(KADEMLIA_PARTIAL_RES);
bio2.writeUInt16(prefs->getTCPPort());
bio2.writeArray(tth, sizeof(tth));
bio2.writeUInt8(cnt2);
CKademlia::debugMsg("Sent UDP OpCode KADEMLIA_PARTIAL_RES (%u)", ip);
sendPacket(response, 29 + sizeof(unsigned short) * cnt2 * 2, ip, udpport);
} catch (...) {TRACE("Exception in Kademlia Partial Request\n");}
}
void CKademliaUDPListener::processPartialResponse (const byte *packetData, const uint32 lenPacket, const sockaddr_in *senderAddress)
{
byte tth[24];
try
{
if (lenPacket < 27){
ASSERT(0);
return;
}
CByteIO bio(packetData, lenPacket);
uint16 tcpport = bio.readUInt16();
if(tcpport == 0){
ASSERT(0); // TODO: This request is sent from passive user, ignore it now.
return;
}
bio.readArray(tth, sizeof(tth));
uint8 cnt = bio.readUInt8();
if(lenPacket < (uint32)(27 + cnt * sizeof(unsigned short) * 2)){
ASSERT(0);
return;
}
uint32 ip = ntohl(senderAddress->sin_addr.s_addr);
uint16 udpport = ntohs(senderAddress->sin_port);
if(partialResponseHandler == NULL ||
!partialResponseHandler(ip, tcpport, udpport, tth, cnt, (uint16*)(packetData + 27)))
return;
} catch (...) {TRACE("Exception in Kademlia Partial Response\n");}
}
void CKademliaUDPListener::processRevConnectRequest (const byte *packetData, const uint32 lenPacket, const sockaddr_in *senderAddress)
{
try
{
if(revConnectRequestHandler == NULL){
CKademlia::debugMsg("No Handler For UDP OpCode KADEMLIA_REVCONNECT_REQ");
}
if (lenPacket < 2){
ASSERT(0);
return;
}
CByteIO bio(packetData, lenPacket);
uint16 tcpport = bio.readUInt16();
uint32 ip = ntohl(senderAddress->sin_addr.s_addr);
uint16 udpport = ntohs(senderAddress->sin_port);
// Callback to handler
revConnectRequestHandler(ip, tcpport, udpport, packetData + 2, lenPacket - 2);
} catch (...) {TRACE("Exception in Kademlia RevConnect Request\n");}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -