📄 listensocket.cpp
字号:
if (thePrefs.GetDebugSourceExchange())
AddDebugLogLine(false, _T("SXRecv: Client source request; %s, %s"), client->DbgGetClientInfo(), DbgGetFileInfo((uchar*)packet));
//first check shared file list, then download list
CKnownFile* file;
if ((file = theApp.sharedfiles->GetFileByID((uchar*)packet)) != NULL ||
(file = theApp.downloadqueue->GetFileByID((uchar*)packet)) != NULL)
{
DWORD dwTimePassed = ::GetTickCount() - client->GetLastSrcReqTime() + CONNECTION_LATENCY;
bool bNeverAskedBefore = client->GetLastSrcReqTime() == 0;
if(
//if not complete and file is rare
( file->IsPartFile()
&& (bNeverAskedBefore || dwTimePassed > SOURCECLIENTREASKS)
&& ((CPartFile*)file)->GetSourceCount() <= RARE_FILE
) ||
//OR if file is not rare or if file is complete
( (bNeverAskedBefore || dwTimePassed > SOURCECLIENTREASKS * MINCOMMONPENALTY) )
)
{
client->SetLastSrcReqTime();
Packet* tosend = file->CreateSrcInfoPacket(client);
if(tosend)
{
if (thePrefs.GetDebugClientTCPLevel() > 0)
DebugSend("OP__AnswerSources", client, (char*)file->GetFileHash());
theStats.AddUpDataOverheadSourceExchange(tosend->size);
SendPacket(tosend, true, true);
}
}
}
else
client->CheckFailedFileIdReqs((uchar*)packet);
}
break;
}
case OP_ANSWERSOURCES:
{
if (thePrefs.GetDebugClientTCPLevel() > 0)
DebugRecv("OP_AnswerSources", client, packet);
theStats.AddDownDataOverheadSourceExchange(uRawSize);
client->CheckHandshakeFinished(OP_EMULEPROT, opcode);
CSafeMemFile data((BYTE*)packet,size);
uchar hash[16];
data.ReadHash16(hash);
CKnownFile* file = theApp.downloadqueue->GetFileByID(hash);
if(file)
{
if (file->IsPartFile())
{
//set the client's answer time
client->SetLastSrcAnswerTime();
//and set the file's last answer time
((CPartFile*)file)->SetLastAnsweredTime();
((CPartFile*)file)->AddClientSources(&data, client->GetSourceExchangeVersion(), client);
}
}
else
client->CheckFailedFileIdReqs(hash);
break;
}
case OP_FILEDESC:
{
if (thePrefs.GetDebugClientTCPLevel() > 0)
DebugRecv("OP_FileDesc", client);
theStats.AddDownDataOverheadFileRequest(uRawSize);
client->CheckHandshakeFinished(OP_EMULEPROT, opcode);
client->ProcessMuleCommentPacket(packet,size);
break;
}
case OP_REQUESTPREVIEW:
{
if (thePrefs.GetDebugClientTCPLevel() > 0)
DebugRecv("OP_RequestPreView", client);
theStats.AddDownDataOverheadOther(uRawSize);
client->CheckHandshakeFinished(OP_EMULEPROT, opcode);
if (thePrefs.CanSeeShares()==vsfaEverybody || (thePrefs.CanSeeShares()==vsfaFriends && client->IsFriend()))
{
client->ProcessPreviewReq(packet,size);
if (thePrefs.GetVerbose())
AddDebugLogLine(true,_T("Client '%s' (%s) requested Preview - accepted"), client->GetUserName(), ipstr(client->GetConnectIP()));
}
else
{
// we don't send any answer here, because the client should know that he was not allowed to ask
if (thePrefs.GetVerbose())
AddDebugLogLine(true,_T("Client '%s' (%s) requested Preview - denied"), client->GetUserName(), ipstr(client->GetConnectIP()));
}
break;
}
case OP_PREVIEWANSWER:
{
if (thePrefs.GetDebugClientTCPLevel() > 0)
DebugRecv("OP_PreviewAnswer", client);
theStats.AddDownDataOverheadOther(uRawSize);
client->CheckHandshakeFinished(OP_EMULEPROT, opcode);
client->ProcessPreviewAnswer(packet, size);
break;
}
case OP_PEERCACHE_QUERY:
{
theStats.AddDownDataOverheadFileRequest(uRawSize);
if (!client->ProcessPeerCacheQuery(packet, size))
{
CSafeMemFile dataSend(128);
dataSend.WriteUInt8(PCPCK_VERSION);
dataSend.WriteUInt8(PCOP_NONE);
if (thePrefs.GetDebugClientTCPLevel() > 0){
DebugSend("OP__PeerCacheAnswer", client);
Debug(_T(" %s\n"), _T("Not supported"));
}
Packet* pEd2kPacket = new Packet(&dataSend, OP_EMULEPROT, OP_PEERCACHE_ANSWER);
theStats.AddUpDataOverheadFileRequest(pEd2kPacket->size);
SendPacket(pEd2kPacket);
}
break;
}
case OP_PEERCACHE_ANSWER:
{
theStats.AddDownDataOverheadFileRequest(uRawSize);
if ( (!client->ProcessPeerCacheAnswer(packet, size)) && client->GetDownloadState() != DS_NONEEDEDPARTS)
{
// We have sent a PeerCache Query to the remote client, for any reason the remote client
// can not process it -> fall back to ed2k download.
client->SetPeerCacheDownState(PCDS_NONE);
ASSERT( client->m_pPCDownSocket == NULL );
// PC-TODO: Check client state.
ASSERT( client->GetDownloadState() == DS_DOWNLOADING );
client->SetDownloadState(DS_ONQUEUE, _T("Peer cache query trouble")); // clear block requests
if (client)
client->StartDownload();
}
break;
}
case OP_PEERCACHE_ACK:
{
theStats.AddDownDataOverheadFileRequest(uRawSize);
client->ProcessPeerCacheAcknowledge(packet, size);
break;
}
case OP_PUBLICIP_ANSWER:
{
theStats.AddDownDataOverheadOther(uRawSize);
if (thePrefs.GetDebugClientTCPLevel() > 0)
DebugRecv("OP_PublicIPAns", client);
client->ProcessPublicIPAnswer((BYTE*)packet,size);
break;
}
case OP_PUBLICIP_REQ:
{
theStats.AddDownDataOverheadOther(uRawSize);
if (thePrefs.GetDebugClientTCPLevel() > 0)
DebugRecv("OP_PublicIPReq", client);
if (thePrefs.GetDebugClientTCPLevel() > 0)
DebugSend("OP__PublicIPAns", client);
Packet* pPacket = new Packet(OP_PUBLICIP_ANSWER, 4, OP_EMULEPROT);
PokeUInt32(pPacket->pBuffer, client->GetIP());
theStats.AddUpDataOverheadOther(pPacket->size);
SendPacket(pPacket);
break;
}
case OP_PORTTEST:
{
theStats.AddDownDataOverheadOther(uRawSize);
if (thePrefs.GetDebugClientTCPLevel() > 0)
DebugRecv("OP_PortTest", client);
m_bPortTestCon=true;
Packet* replypacket = new Packet(OP_PORTTEST, 1);
replypacket->pBuffer[0]=0x12;
SendPacket(replypacket);
break;
}
case OP_CALLBACK:
{
theStats.AddDownDataOverheadOther(uRawSize);
if (thePrefs.GetDebugClientTCPLevel() > 0)
DebugRecv("OP_Callback", client);
if(!Kademlia::CKademlia::isRunning())
break;
CSafeMemFile data((BYTE*)packet,size);
Kademlia::CUInt128 check;
data.ReadUInt128(&check);
check.xor(Kademlia::CUInt128(true));
if( check.compareTo(Kademlia::CKademlia::getPrefs()->getKadID()))
break;
Kademlia::CUInt128 fileid;
data.ReadUInt128(&fileid);
uchar fileid2[16];
fileid.toByteArray(fileid2);
CKnownFile* reqfile;
if ( (reqfile = theApp.sharedfiles->GetFileByID(fileid2)) == NULL )
{
if ( (reqfile = theApp.downloadqueue->GetFileByID(fileid2)) == NULL)
{
client->CheckFailedFileIdReqs(fileid2);
break;
}
}
uint32 ip = data.ReadUInt32();
uint16 tcp = data.ReadUInt16();
CUpDownClient* callback;
callback = theApp.clientlist->FindClientByIP(ntohl(ip), tcp);
if( callback == NULL )
{
callback = new CUpDownClient(NULL,tcp,ip,0,0);
theApp.clientlist->AddClient(callback);
}
callback->TryToConnect(true);
break;
}
case OP_BUDDYPING:
{
theStats.AddDownDataOverheadOther(uRawSize);
if (thePrefs.GetDebugClientTCPLevel() > 0)
DebugRecv("OP_BuddyPing", client);
CUpDownClient* buddy = theApp.clientlist->GetBuddy();
if( buddy != client || client->GetKadVersion() == 0 || !client->AllowIncomeingBuddyPingPong() )
//This ping was not from our buddy or wrong version or packet sent to fast. Ignore
break;
Packet* replypacket = new Packet(OP_BUDDYPONG, 0, OP_EMULEPROT);
SendPacket(replypacket);
client->SetLastBuddyPingPongTime();
break;
}
case OP_BUDDYPONG:
{
theStats.AddDownDataOverheadOther(uRawSize);
if (thePrefs.GetDebugClientTCPLevel() > 0)
DebugRecv("OP_BuddyPong", client);
CUpDownClient* buddy = theApp.clientlist->GetBuddy();
if( buddy != client || client->GetKadVersion() == 0 )
//This pong was not from our buddy or wrong version. Ignore
break;
client->SetLastBuddyPingPongTime();
//All this is for is to reset our socket timeout.
break;
}
case OP_REASKCALLBACKTCP:
{
theStats.AddDownDataOverheadFileRequest(uRawSize);
CUpDownClient* buddy = theApp.clientlist->GetBuddy();
if( buddy != client )
//This callback was not from our buddy.. Ignore.
break;
CSafeMemFile data_in((uchar*)packet, size);
uint32 destip = data_in.ReadUInt32();
uint16 destport = data_in.ReadUInt16();
uchar reqfilehash[16];
data_in.ReadHash16(reqfilehash);
CKnownFile* reqfile = theApp.sharedfiles->GetFileByID(reqfilehash);
if (!reqfile)
{
if (thePrefs.GetDebugClientUDPLevel() > 0)
{
DebugRecv("OP_ReaskCallbackTCP", NULL, (char*)reqfilehash, destip);
DebugSend("OP__FileNotFound", NULL);
}
Packet* response = new Packet(OP_FILENOTFOUND,0,OP_EMULEPROT);
theStats.AddUpDataOverheadFileRequest(response->size);
theApp.clientudp->SendPacket(response, destip, destport);
break;
}
CUpDownClient* sender = theApp.uploadqueue->GetWaitingClientByIP_UDP(destip, destport);
if (sender)
{
if (thePrefs.GetDebugClientUDPLevel() > 0)
DebugRecv("OP_ReaskCallbackTCP", sender, (char*)reqfilehash, destip);
//Make sure we are still thinking about the same file
if (md4cmp(reqfilehash, sender->GetUploadFileID()) == 0)
{
sender->AddAskedCount();
sender->SetLastUpRequest();
//I messed up when I first added extended info to UDP
//I should have originally used the entire ProcessExtenedInfo the first time.
//So now I am forced to check UDPVersion to see if we are sending all the extended info.
//For now on, we should not have to change anything here if we change
//anything to the extended info data as this will be taken care of in ProcessExtendedInfo()
//Update extended info.
if (sender->GetUDPVersion() > 3)
{
sender->ProcessExtendedInfo(&data_in, reqfile);
}
//Update our complete source counts.
else if (sender->GetUDPVersion() > 2)
{
uint16 nCompleteCountLast= sender->GetUpCompleteSourcesCount();
uint16 nCompleteCountNew = data_in.ReadUInt16();
sender->SetUpCompleteSourcesCount(nCompleteCountNew);
if (nCompleteCountLast != nCompleteCountNew)
{
reqfile->UpdatePartsInfo();
}
}
CSafeMemFile data_out(128);
if(sender->GetUDPVersion() > 3)
{
if (reqfile->IsPartFile())
((CPartFile*)reqfile)->WritePartStatus(&data_out);
else
data_out.WriteUInt16(0);
}
data_out.WriteUInt16(theApp.uploadqueue->GetWaitingPosition(sender));
if (thePrefs.GetDebugClientUDPLevel() > 0)
DebugSend("OP__ReaskAck", sender);
Packet* response = new Packet(&data_out, OP_EMULEPROT);
response->opcode = OP_REASKACK;
theStats.AddUpDataOverheadFileRequest(response->size);
theApp.clientudp->SendPacket(response, destip, destport);
}
else
{
DebugLogWarning(_T("Client UDP socket; OP_REASKCALLBACKTCP; reqfile does not match"));
TRACE(_T("reqfile: %s\n"), DbgGetFileInfo(reqfile->GetFileHash()));
TRACE(_T("sender->GetRequestFile(): %s\n"), sender->GetRequestFile() ? DbgGetFileInfo(sender->GetRequestFile()->GetFileHash()) : _T("(null)"));
}
}
else
{
if (thePrefs.GetDebugClientUDPLevel() > 0)
DebugRecv("OP_ReaskCallbackTCP", NULL, (char*)reqfilehash, destip);
if (((uint32)theApp.uploadqueue->GetWaitingUserCount() + 50) > thePrefs.GetQueueSize())
{
if (thePrefs.GetDebugClientUDPLevel() > 0)
DebugSend("OP__QueueFull", NULL);
Packet* response = new Packet(OP_QUEUEFULL,0,OP_EMULEPROT);
theStats.AddUpDataOverheadFileRequest(response->size);
theApp.clientudp->SendPacket(response, destip, destport);
}
}
break;
}
case OP_AICHANSWER:
{
theStats.AddDownDataOverheadOther(uRawSize);
if (thePrefs.GetDebugClientTCPLevel() > 0)
DebugRecv("OP_AichAnswer", client);
client->ProcessAICHAnswer(packet,size);
break;
}
case OP_AICHREQUEST:
{
theStats.A
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -