// Full debug output of all data void CCorruptionBlackBox::DumpAll() { #ifdef __DEBUG__ AddDebugLogLineN(logPartFile, wxT("CBB Dump Records")); std::map<uint16, CRecordList>::iterator it = m_Records.begin(); for (; it != m_Records.end(); ++it) { uint16 block = it->first; CRecordList & list = it->second; for (CRecordList::iterator it2 = list.begin(); it2 != list.end(); ++it2) { AddDebugLogLineN(logPartFile, CFormat(wxT("CBBD %6d %.16s %10d - %10d")) % block % Uint32toStringIP(it2->m_dwIP) % it2->m_nStartPos % it2->m_nEndPos); } } if (!m_goodClients.empty()) { AddDebugLogLineN(logPartFile, wxT("CBB Dump good Clients")); CCBBClientMap::iterator it3 = m_goodClients.begin(); for (; it3 != m_goodClients.end(); ++it3) { AddDebugLogLineN(logPartFile, CFormat(wxT("CBBD %.16s good %10d")) % Uint32toStringIP(it3->first) % it3->second.m_downloaded); } } if (!m_badClients.empty()) { AddDebugLogLineN(logPartFile, wxT("CBB Dump bad Clients")); CCBBClientMap::iterator it3 = m_badClients.begin(); for (; it3 != m_badClients.end(); ++it3) { AddDebugLogLineN(logPartFile, CFormat(wxT("CBBD %.16s bad %10d")) % Uint32toStringIP(it3->first) % it3->second.m_downloaded); } } #endif }
bool CDownloadQueue::AddED2KLink( const CED2KServerLink* link ) { CServer *server = new CServer( link->GetPort(), Uint32toStringIP( link->GetIP() ) ); server->SetListName( Uint32toStringIP( link->GetIP() ) ); theApp->serverlist->AddServer(server); Notify_ServerAdd(server); return true; }
// Check all clients that uploaded corrupted data, // and ban them if they didn't upload enough good data too. void CCorruptionBlackBox::EvaluateData() { CCBBClientMap::iterator it = m_badClients.begin(); for (; it != m_badClients.end(); ++it) { uint32 ip = it->first; uint64 bad = it->second.m_downloaded; if (!bad) { wxFAIL; // this should not happen continue; } uint64 good = 0; CCBBClientMap::iterator it2 = m_goodClients.find(ip); if (it2 != m_goodClients.end()) { good = it2->second.m_downloaded; } int nCorruptPercentage = bad * 100 / (bad + good); if (nCorruptPercentage > CBB_BANTHRESHOLD) { CUpDownClient* pEvilClient = theApp->clientlist->FindClientByIP(ip); wxString clientName; if (pEvilClient != NULL) { clientName = pEvilClient->GetClientShortInfo(); AddDebugLogLineN(logPartFile, CFormat(wxT("CorruptionBlackBox(%s): Banning: Found client which sent %d of %d corrupted data, %s")) % m_partNumber % bad % (good + bad) % pEvilClient->GetClientFullInfo()); theApp->clientlist->AddTrackClient(pEvilClient); pEvilClient->Ban(); // Identified as sender of corrupt data // Stop download right away pEvilClient->SetDownloadState(DS_BANNED); if (pEvilClient->Disconnected(wxT("Upload of corrupted data"))) { pEvilClient->Safe_Delete(); } } else { clientName = Uint32toStringIP(ip); theApp->clientlist->AddBannedClient(ip); } AddLogLineN(CFormat(_("Banned client %s for sending %s corrupt data of %s total for the file '%s'")) % clientName % CastItoXBytes(bad) % CastItoXBytes(good + bad) % m_fileName); } else { CUpDownClient* pSuspectClient = theApp->clientlist->FindClientByIP(ip); if (pSuspectClient != NULL) { AddDebugLogLineN(logPartFile, CFormat(wxT("CorruptionBlackBox(%s): Reporting: Found client which probably sent %d of %d corrupted data, but it is within the acceptable limit, %s")) % m_partNumber % bad % (good + bad) % pSuspectClient->GetClientFullInfo()); theApp->clientlist->AddTrackClient(pSuspectClient); } else { AddDebugLogLineN(logPartFile, CFormat(wxT("CorruptionBlackBox(%s): Reporting: Found client which probably sent %d of %d corrupted data, but it is within the acceptable limit, %s")) % m_partNumber % bad % (good + bad) % Uint32toStringIP(ip)); } } } }
// Store a piece of received data (don't know if it's good or bad yet). // Data is stored in a list for the chunk in belongs to. void CCorruptionBlackBox::TransferredData(uint64 nStartPos, uint64 nEndPos, uint32 senderIP) { if (nStartPos > nEndPos) { wxFAIL; return; } // convert pos to relative block pos uint16 nPart = (uint16)(nStartPos / PARTSIZE); uint32 nRelStartPos = nStartPos - nPart*PARTSIZE; uint32 nRelEndPos = nEndPos - nPart*PARTSIZE; if (nRelEndPos >= PARTSIZE) { // data crosses the partborder, split it // (for the fun of it, this should never happen) nRelEndPos = PARTSIZE-1; TransferredData((nPart+1)*PARTSIZE, nEndPos, senderIP); } // // Let's keep things simple. // We don't request data we already have. // We check if received data exceeds block boundaries. // -> There should not be much overlap here. // So just stuff everything received into the list and only join adjacent blocks. // CRecordList & list = m_Records[nPart]; // this creates the entry if it doesn't exist yet bool merged = false; for (CRecordList::iterator it = list.begin(); it != list.end() && !merged; ++it) { merged = it->Merge(nRelStartPos, nRelEndPos, senderIP); } if (!merged) { list.push_back(CCBBRecord(nRelStartPos, nRelEndPos, senderIP)); AddDebugLogLineN(logPartFile, CFormat(wxT("CorruptionBlackBox(%s): transferred: new record for part %d (%d - %d, %s)")) % m_partNumber % nPart % nRelStartPos % nRelEndPos % Uint32toStringIP(senderIP)); } }
CChatSession* CChatSelector::StartSession(uint64 client_id, const wxString& client_name, bool show) { // Check to see if we've already opened a session for this user if ( GetPageByClientID( client_id ) ) { if ( show ) { SetSelection( GetTabByClientID( client_id ) ); } return NULL; } CChatSession* chatsession = new CChatSession(this); chatsession->m_client_id = client_id; wxString text; text = wxT(" *** ") + (CFormat(_("Chat-Session Started: %s (%s:%u) - %s %s")) % client_name % Uint32toStringIP(IP_FROM_GUI_ID(client_id)) % PORT_FROM_GUI_ID(client_id) % wxDateTime::Now().FormatISODate() % wxDateTime::Now().FormatISOTime()); chatsession->AddText( text, COLOR_RED ); AddPage(chatsession, client_name, show, 0); CUserEvents::ProcessEvent(CUserEvents::NewChatSession, &client_name); return chatsession; }
void CDownloadQueue::CheckAndAddKnownSource(CPartFile* sender,CUpDownClient* source) { // Kad reviewed if (sender->IsStopped()) { return; } // Filter sources which are known to be dead/useless if ( sender->IsDeadSource(source) ) { return; } // "Filter LAN IPs" -- this may be needed here in case we are connected to the internet and are also connected // to a LAN and some client from within the LAN connected to us. Though this situation may be supported in future // by adding that client to the source list and filtering that client's LAN IP when sending sources to // a client within the internet. // // "IPfilter" is not needed here, because that "known" client was already IPfiltered when receiving OP_HELLO. if (!source->HasLowID()) { uint32 nClientIP = wxUINT32_SWAP_ALWAYS(source->GetUserIDHybrid()); if (!IsGoodIP(nClientIP, thePrefs::FilterLanIPs())) { // check for 0-IP, localhost and LAN addresses AddDebugLogLineN(logIPFilter, wxT("Ignored already known source with IP=%s") + Uint32toStringIP(nClientIP)); return; } } // Filter sources which are incompatible with our encryption setting (one requires it, and the other one doesn't supports it) if ( (source->RequiresCryptLayer() && (!thePrefs::IsClientCryptLayerSupported() || !source->HasValidHash())) || (thePrefs::IsClientCryptLayerRequired() && (!source->SupportsCryptLayer() || !source->HasValidHash()))) { source->Safe_Delete(); return; } CPartFile* file = source->GetRequestFile(); // Check if the file is already queued for something else if ( file ) { if ( file != sender ) { if ( source->AddRequestForAnotherFile( sender ) ) { Notify_SourceCtrlAddSource( sender, CCLIENTREF(source, wxT("CDownloadQueue::CheckAndAddKnownSource Notify_SourceCtrlAddSource 1")), A4AF_SOURCE ); } } } else { source->SetRequestFile( sender ); if ( source->GetFileRating() || !source->GetFileComment().IsEmpty() ) { sender->UpdateFileRatingCommentAvail(); } source->SetSourceFrom(SF_PASSIVE); sender->AddSource( source ); Notify_SourceCtrlAddSource( sender, CCLIENTREF(source, wxT("CDownloadQueue::CheckAndAddKnownSource Notify_SourceCtrlAddSource 2")), UNAVAILABLE_SOURCE); } }
bool CClientList::SendChatMessage(uint64 client_id, const wxString& message) { CUpDownClient* client = FindClientByIP(IP_FROM_GUI_ID(client_id), PORT_FROM_GUI_ID(client_id)); AddDebugLogLineN( logClient, wxT("Trying to Send Message.") ); if (client) { AddDebugLogLineN( logClient, wxT("Sending.") ); } else { AddDebugLogLineC( logClient, CFormat( wxT("No client (GUI_ID %lli [%s:%llu]) found in CClientList::SendChatMessage(). Creating") ) % client_id % Uint32toStringIP(IP_FROM_GUI_ID(client_id)) % PORT_FROM_GUI_ID(client_id) ); client = new CUpDownClient(PORT_FROM_GUI_ID(client_id),IP_FROM_GUI_ID(client_id),0,0,NULL, true, true); AddClient(client); } return client->SendChatMessage(message); }
bool CChatSelector::ProcessMessage(uint64 sender_id, const wxString& message) { CChatSession* session = GetPageByClientID(sender_id); // Try to get the name (core sent it?) int separator = message.Find(wxT("|")); wxString client_name; wxString client_message; if (separator != -1) { client_name = message.Left(separator); client_message = message.Mid(separator+1); } else { // No need to define client_name. If needed, will be build on tab creation. client_message = message; } bool newtab = !session; if ( !session ) { // This must be a mesage from a client that is not already chatting if (client_name.IsEmpty()) { // Core did not send us the name. // This must NOT happen. // Build a client name based on the ID uint32 ip = IP_FROM_GUI_ID(sender_id); client_name = CFormat(wxT("IP: %s Port: %u")) % Uint32toStringIP(ip) % PORT_FROM_GUI_ID(sender_id); } session = StartSession( sender_id, client_name, true ); } // Other client connected after disconnection or a new session if ( !session->m_active ) { session->m_active = true; session->AddText( _("*** Connected to Client ***"), COLOR_RED ); } // Page text is client name session->AddText( GetPageText(GetTabByClientID(sender_id)), COLOR_BLUE, false ); session->AddText( wxT(": ") + client_message, COLOR_BLACK ); return newtab; }
wxMenu* CMuleTrayIcon::CreatePopupMenu() { // Creates dinamically the menu to show the user. wxMenu *traymenu = new wxMenu(); traymenu->SetTitle(_("aMule Tray Menu")); // Build the Top string name wxString label = MOD_VERSION_LONG; traymenu->Append(TRAY_MENU_INFO, label); traymenu->AppendSeparator(); label = wxString(_("Speed limits:")) + wxT(" "); // Check for upload limits unsigned int max_upload = thePrefs::GetMaxUpload(); if ( max_upload == UNLIMITED ) { label += _("UL: None"); } else { label += CFormat(_("UL: %u")) % max_upload; } label += wxT(", "); // Check for download limits unsigned int max_download = thePrefs::GetMaxDownload(); if ( max_download == UNLIMITED ) { label += _("DL: None"); } else { label += CFormat(_("DL: %u")) % max_download; } traymenu->Append(TRAY_MENU_INFO, label); label = CFormat(_("Download speed: %.1f")) % (theStats::GetDownloadRate() / 1024.0); traymenu->Append(TRAY_MENU_INFO, label); label = CFormat(_("Upload speed: %.1f")) % (theStats::GetUploadRate() / 1024.0); traymenu->Append(TRAY_MENU_INFO, label); traymenu->AppendSeparator(); // Client Info wxMenu* ClientInfoMenu = new wxMenu(); ClientInfoMenu->SetTitle(_("Client Information")); // User nick-name { wxString temp = CFormat(_("Nickname: %s")) % ( thePrefs::GetUserNick().IsEmpty() ? wxString(_("No Nickname Selected!")) : thePrefs::GetUserNick() ); ClientInfoMenu->Append(TRAY_MENU_CLIENTINFO_ITEM,temp); } // Client ID { wxString temp = _("ClientID: "); if (theApp->IsConnectedED2K()) { temp += CFormat(wxT("%u")) % theApp->GetED2KID(); } else { temp += _("Not connected"); } ClientInfoMenu->Append(TRAY_MENU_CLIENTINFO_ITEM,temp); } // Current Server and Server IP { wxString temp_name = _("ServerName: "); wxString temp_ip = _("ServerIP: "); if ( theApp->serverconnect->GetCurrentServer() ) { temp_name += theApp->serverconnect->GetCurrentServer()->GetListName(); temp_ip += theApp->serverconnect->GetCurrentServer()->GetFullIP(); } else { temp_name += _("Not connected"); temp_ip += _("Not Connected"); } ClientInfoMenu->Append(TRAY_MENU_CLIENTINFO_ITEM,temp_name); ClientInfoMenu->Append(TRAY_MENU_CLIENTINFO_ITEM,temp_ip); } // IP Address { wxString temp = CFormat(_("IP: %s")) % ( (theApp->GetPublicIP()) ? Uint32toStringIP(theApp->GetPublicIP()) : wxString(_("Unknown")) ); ClientInfoMenu->Append(TRAY_MENU_CLIENTINFO_ITEM,temp); } // TCP PORT { wxString temp; if (thePrefs::GetPort()) { temp = CFormat(_("TCP port: %d")) % thePrefs::GetPort(); } else { temp=_("TCP port: Not ready"); } ClientInfoMenu->Append(TRAY_MENU_CLIENTINFO_ITEM,temp); } // UDP PORT { wxString temp; if (thePrefs::GetEffectiveUDPPort()) { temp = CFormat(_("UDP port: %d")) % thePrefs::GetEffectiveUDPPort(); } else { temp=_("UDP port: Not ready"); } ClientInfoMenu->Append(TRAY_MENU_CLIENTINFO_ITEM,temp); } // Online Signature { wxString temp; if (thePrefs::IsOnlineSignatureEnabled()) { temp=_("Online Signature: Enabled"); } else { temp=_("Online Signature: Disabled"); } ClientInfoMenu->Append(TRAY_MENU_CLIENTINFO_ITEM,temp); } // Uptime { wxString temp = CFormat(_("Uptime: %s")) % CastSecondsToHM(theStats::GetUptimeSeconds()); ClientInfoMenu->Append(TRAY_MENU_CLIENTINFO_ITEM,temp); } // Number of shared files { wxString temp = CFormat(_("Shared files: %d")) % theStats::GetSharedFileCount(); ClientInfoMenu->Append(TRAY_MENU_CLIENTINFO_ITEM,temp); } // Number of queued clients { wxString temp = CFormat(_("Queued clients: %d")) % theStats::GetWaitingUserCount(); ClientInfoMenu->Append(TRAY_MENU_CLIENTINFO_ITEM,temp); } // Total Downloaded { wxString temp = CastItoXBytes(theStats::GetTotalReceivedBytes()); temp = CFormat(_("Total DL: %s")) % temp; ClientInfoMenu->Append(TRAY_MENU_CLIENTINFO_ITEM,temp); } // Total Uploaded { wxString temp = CastItoXBytes(theStats::GetTotalSentBytes()); temp = CFormat(_("Total UL: %s")) % temp; ClientInfoMenu->Append(TRAY_MENU_CLIENTINFO_ITEM,temp); } traymenu->Append(TRAY_MENU_CLIENTINFO,ClientInfoMenu->GetTitle(),ClientInfoMenu); // Separator traymenu->AppendSeparator(); // Upload Speed sub-menu wxMenu* UploadSpeedMenu = new wxMenu(); UploadSpeedMenu->SetTitle(_("Upload limit")); // Download Speed sub-menu wxMenu* DownloadSpeedMenu = new wxMenu(); DownloadSpeedMenu->SetTitle(_("Download limit")); // Upload Speed sub-menu { UploadSpeedMenu->Append(UPLOAD_ITEM1, _("Unlimited")); uint32 max_ul_speed = thePrefs::GetMaxGraphUploadRate(); if ( max_ul_speed == UNLIMITED ) { max_ul_speed = 100; } else if ( max_ul_speed < 10 ) { max_ul_speed = 10; } for ( int i = 0; i < 5; i++ ) { unsigned int tempspeed = (unsigned int)((double)max_ul_speed / 5) * (5 - i); wxString temp = CFormat(wxT("%u %s")) % tempspeed % _("kB/s"); UploadSpeedMenu->Append((int)UPLOAD_ITEM1+i+1,temp); } } traymenu->Append(0,UploadSpeedMenu->GetTitle(),UploadSpeedMenu); // Download Speed sub-menu { DownloadSpeedMenu->Append(DOWNLOAD_ITEM1, _("Unlimited")); uint32 max_dl_speed = thePrefs::GetMaxGraphDownloadRate(); if ( max_dl_speed == UNLIMITED ) { max_dl_speed = 100; } else if ( max_dl_speed < 10 ) { max_dl_speed = 10; } for ( int i = 0; i < 5; i++ ) { unsigned int tempspeed = (unsigned int)((double)max_dl_speed / 5) * (5 - i); wxString temp = CFormat(wxT("%d %s")) % tempspeed % _("kB/s"); DownloadSpeedMenu->Append((int)DOWNLOAD_ITEM1+i+1,temp); } } traymenu->Append(0,DownloadSpeedMenu->GetTitle(),DownloadSpeedMenu); // Separator traymenu->AppendSeparator(); if (theApp->IsConnected()) { //Disconnection Speed item traymenu->Append(TRAY_MENU_DISCONNECT, _("Disconnect")); } else { //Connect item traymenu->Append(TRAY_MENU_CONNECT, _("Connect")); } // Separator traymenu->AppendSeparator(); if (theApp->amuledlg->IsShown()) { //hide item traymenu->Append(TRAY_MENU_HIDE, _("Hide aMule")); } else { //show item traymenu->Append(TRAY_MENU_SHOW, _("Show aMule")); } // Separator traymenu->AppendSeparator(); // Exit item traymenu->Append(TRAY_MENU_EXIT, _("Exit")); return traymenu; }
void CDownloadQueue::KademliaSearchFile(uint32_t searchID, const Kademlia::CUInt128* pcontactID, const Kademlia::CUInt128* pbuddyID, uint8_t type, uint32_t ip, uint16_t tcp, uint16_t udp, uint32_t buddyip, uint16_t buddyport, uint8_t byCryptOptions) { AddDebugLogLineN(logKadSearch, CFormat(wxT("Search result sources (type %i)")) % type); //Safety measure to make sure we are looking for these sources CPartFile* temp = GetFileByKadFileSearchID(searchID); if( !temp ) { AddDebugLogLineN(logKadSearch, wxT("This is not the file we're looking for...")); return; } //Do we need more sources? if(!(!temp->IsStopped() && thePrefs::GetMaxSourcePerFile() > temp->GetSourceCount())) { AddDebugLogLineN(logKadSearch, wxT("No more sources needed for this file")); return; } uint32_t ED2KID = wxUINT32_SWAP_ALWAYS(ip); if (theApp->ipfilter->IsFiltered(ED2KID)) { AddDebugLogLineN(logKadSearch, wxT("Source ip got filtered")); AddDebugLogLineN(logIPFilter, CFormat(wxT("IPfiltered source IP=%s received from Kademlia")) % Uint32toStringIP(ED2KID)); return; } if( (ip == Kademlia::CKademlia::GetIPAddress() || ED2KID == theApp->GetED2KID()) && tcp == thePrefs::GetPort()) { AddDebugLogLineN(logKadSearch, wxT("Trying to add myself as source, ignore")); return; } CUpDownClient* ctemp = NULL; switch (type) { case 4: case 1: { // NonFirewalled users if(!tcp) { AddDebugLogLineN(logKadSearch, CFormat(wxT("Ignored source (IP=%s) received from Kademlia, no tcp port received")) % Uint32toStringIP(ip)); return; } if (!IsGoodIP(ED2KID,thePrefs::FilterLanIPs())) { AddDebugLogLineN(logKadSearch, CFormat(wxT("%s got filtered")) % Uint32toStringIP(ED2KID)); AddDebugLogLineN(logIPFilter, CFormat(wxT("Ignored source (IP=%s) received from Kademlia, filtered")) % Uint32toStringIP(ED2KID)); return; } ctemp = new CUpDownClient(tcp, ip, 0, 0, temp, false, true); ctemp->SetSourceFrom(SF_KADEMLIA); // not actually sent or needed for HighID sources //ctemp->SetServerIP(serverip); //ctemp->SetServerPort(serverport); ctemp->SetKadPort(udp); byte cID[16]; pcontactID->ToByteArray(cID); ctemp->SetUserHash(CMD4Hash(cID)); break; } case 2: { // Don't use this type... Some clients will process it wrong.. break; } case 5: case 3: { // This will be a firewalled client connected to Kad only. // We set the clientID to 1 as a Kad user only has 1 buddy. ctemp = new CUpDownClient(tcp, 1, 0, 0, temp, false, true); // The only reason we set the real IP is for when we get a callback // from this firewalled source, the compare method will match them. ctemp->SetSourceFrom(SF_KADEMLIA); ctemp->SetKadPort(udp); byte cID[16]; pcontactID->ToByteArray(cID); ctemp->SetUserHash(CMD4Hash(cID)); pbuddyID->ToByteArray(cID); ctemp->SetBuddyID(cID); ctemp->SetBuddyIP(buddyip); ctemp->SetBuddyPort(buddyport); break; } case 6: { // firewalled source which supports direct UDP callback // if we are firewalled ourself, the source is useless to us if (theApp->IsFirewalled()) { break; } if ((byCryptOptions & 0x08) == 0){ AddDebugLogLineN(logKadSearch, CFormat(wxT("Received Kad source type 6 (direct callback) which has the direct callback flag not set (%s)")) % Uint32toStringIP(ED2KID)); break; } ctemp = new CUpDownClient(tcp, 1, 0, 0, temp, false, true); ctemp->SetSourceFrom(SF_KADEMLIA); ctemp->SetKadPort(udp); ctemp->SetIP(ED2KID); // need to set the IP address, which cannot be used for TCP but for UDP byte cID[16]; pcontactID->ToByteArray(cID); ctemp->SetUserHash(CMD4Hash(cID)); } } if (ctemp) { // add encryption settings ctemp->SetConnectOptions(byCryptOptions); AddDebugLogLineN(logKadSearch, CFormat(wxT("Happily adding a source (%s) type %d")) % Uint32_16toStringIP_Port(ED2KID, ctemp->GetUserPort()) % type); CheckAndAddSource(temp, ctemp); } }
bool CClientDetailDialog::OnInitDialog() { // Username, Userhash if (!m_client.GetUserName().IsEmpty()) { CastChild(ID_DNAME, wxStaticText)->SetLabel( m_client.GetUserName()); // if we have client name we have userhash wxASSERT(!m_client.GetUserHash().IsEmpty()); CastChild(ID_DHASH, wxStaticText)->SetLabel( m_client.GetUserHash().Encode()); } else { CastChild(ID_DNAME, wxStaticText)->SetLabel(_("Unknown")); CastChild(ID_DHASH, wxStaticText)->SetLabel(_("Unknown")); } // Client Software wxString OSInfo = m_client.GetClientOSInfo(); if (!OSInfo.IsEmpty()) { CastChild(ID_DSOFT, wxStaticText)->SetLabel( m_client.GetSoftStr()+wxT(" (")+OSInfo+wxT(")")); } else { CastChild(ID_DSOFT, wxStaticText)->SetLabel( m_client.GetSoftStr()); } // Client Version CastChild(ID_DVERSION, wxStaticText)->SetLabel( m_client.GetSoftVerStr()); // User ID CastChild(ID_DID, wxStaticText)->SetLabel( CFormat(wxT("%u (%s)")) % m_client.GetUserIDHybrid() % (m_client.HasLowID() ? _("LowID") : _("HighID"))); // Client IP/Port CastChild(ID_DIP, wxStaticText)->SetLabel( CFormat(wxT("%s:%i")) % m_client.GetFullIP() % m_client.GetUserPort()); // Server IP/Port/Name if (m_client.GetServerIP()) { wxString srvaddr = Uint32toStringIP(m_client.GetServerIP()); CastChild(ID_DSIP, wxStaticText)->SetLabel( CFormat(wxT("%s:%i")) % srvaddr % m_client.GetServerPort()); CastChild(ID_DSNAME, wxStaticText)->SetLabel( m_client.GetServerName()); } else { CastChild(ID_DSIP, wxStaticText)->SetLabel(_("Unknown")); CastChild(ID_DSNAME, wxStaticText)->SetLabel(_("Unknown")); } // Obfuscation wxString buffer; switch (m_client.GetObfuscationStatus()) { case OBST_ENABLED: buffer = _("Enabled"); break; case OBST_SUPPORTED: buffer = _("Supported"); break; case OBST_NOT_SUPPORTED: buffer = _("Not supported"); break; case OBST_DISABLED: buffer = _("Disabled"); break; default: buffer = _("Unknown"); break; } CastChild(IDT_OBFUSCATION, wxStaticText)->SetLabel(buffer); // Kad if (m_client.GetKadPort()) { CastChild(IDT_KAD, wxStaticText)->SetLabel(_("Connected")); } else { CastChild(IDT_KAD, wxStaticText)->SetLabel(_("Disconnected")); } // File Name const CKnownFile* file = m_client.GetUploadFile(); if (file) { wxString filename = MakeStringEscaped(file->GetFileName().TruncatePath(60)); CastChild(ID_DDOWNLOADING, wxStaticText)->SetLabel(filename); } else { CastChild(ID_DDOWNLOADING, wxStaticText)->SetLabel(wxT("-")); } // Upload CastChild(ID_DDUP, wxStaticText)->SetLabel( CastItoXBytes(m_client.GetTransferredDown())); // Download CastChild(ID_DDOWN, wxStaticText)->SetLabel( CastItoXBytes(m_client.GetTransferredUp())); // Average Upload Rate CastChild(ID_DAVUR, wxStaticText)->SetLabel( CFormat(_("%.1f kB/s")) % m_client.GetKBpsDown()); // Average Download Rate CastChild(ID_DAVDR, wxStaticText)->SetLabel( CFormat(_("%.1f kB/s")) % (m_client.GetUploadDatarate() / 1024.0f)); // Total Upload CastChild(ID_DUPTOTAL, wxStaticText)->SetLabel( CastItoXBytes(m_client.GetDownloadedTotal())); // Total Download CastChild(ID_DDOWNTOTAL, wxStaticText)->SetLabel( CastItoXBytes(m_client.GetUploadedTotal())); // DL/UP Modifier CastChild(ID_DRATIO, wxStaticText)->SetLabel( CFormat(wxT("%.1f")) % m_client.GetScoreRatio()); // Secure Ident CastChild(IDC_CDIDENT, wxStaticText)->SetLabel( m_client.GetSecureIdentTextStatus()); // Queue Score if (m_client.GetUploadState() != US_NONE) { CastChild(ID_QUEUERANK, wxStaticText)->SetLabel( CFormat(wxT("%u")) % m_client.GetUploadQueueWaitingPosition()); CastChild(ID_DSCORE, wxStaticText)->SetLabel( CFormat(wxT("%u")) % m_client.GetScore()); } else { CastChild(ID_QUEUERANK, wxStaticText)->SetLabel(wxT("-")); CastChild(ID_DSCORE, wxStaticText)->SetLabel(wxT("-")); } Layout(); return true; }
void CServerWnd::UpdateKadInfo() { wxListCtrl* KadInfoList = CastChild( ID_KADINFO, wxListCtrl ); int next_row = 0; KadInfoList->DeleteAllItems(); KadInfoList->InsertItem(next_row, _("Kademlia Status:")); if (theApp->IsKadRunning()) { KadInfoList->SetItem(next_row++, 1, (theApp->IsKadRunningInLanMode() ? _("Running in LAN mode") : _("Running"))); // Connection data KadInfoList->InsertItem(next_row, _("Status:")); KadInfoList->SetItem(next_row++, 1, theApp->IsConnectedKad() ? _("Connected"): _("Disconnected")); if (theApp->IsConnectedKad()) { KadInfoList->InsertItem(next_row, _("Connection State:")); KadInfoList->SetItem(next_row++, 1, theApp->IsFirewalledKad() ? wxString(CFormat(_("Firewalled - open TCP port %d in your router or firewall")) % thePrefs::GetPort()) : wxString(_("OK"))); KadInfoList->InsertItem(next_row, _("UDP Connection State:")); bool UDPFirewalled = theApp->IsFirewalledKadUDP(); KadInfoList->SetItem(next_row++, 1, UDPFirewalled ? wxString(CFormat(_("Firewalled - open UDP port %d in your router or firewall")) % thePrefs::GetUDPPort()) : wxString(_("OK"))); if (theApp->IsFirewalledKad() || UDPFirewalled) { KadInfoList->InsertItem(next_row, _("Firewalled state: ")); wxString BuddyState; switch ( theApp->GetBuddyStatus() ) { case Disconnected: if (!theApp->IsFirewalledKad()) { BuddyState = _("No buddy required - TCP port open"); } else if (!UDPFirewalled) { BuddyState = _("No buddy required - UDP port open"); } else { BuddyState = _("No buddy"); } break; case Connecting: BuddyState = _("Connecting to buddy"); break; case Connected: BuddyState = CFormat(_("Connected to buddy at %s")) % Uint32_16toStringIP_Port(theApp->GetBuddyIP(), theApp->GetBuddyPort()); break; } KadInfoList->SetItem(next_row++, 1, BuddyState); } KadInfoList->InsertItem(next_row, _("IP address:")); KadInfoList->SetItem(next_row++, 1, Uint32toStringIP(theApp->GetKadIPAdress())); // Index info KadInfoList->InsertItem(next_row, _("Indexed sources:")); KadInfoList->SetItem(next_row++, 1, CFormat(wxT("%d")) % theApp->GetKadIndexedSources()); KadInfoList->InsertItem(next_row, _("Indexed keywords:")); KadInfoList->SetItem(next_row++, 1, CFormat(wxT("%d")) % theApp->GetKadIndexedKeywords()); KadInfoList->InsertItem(next_row, _("Indexed notes:")); KadInfoList->SetItem(next_row++, 1, CFormat(wxT("%d")) % theApp->GetKadIndexedNotes()); KadInfoList->InsertItem(next_row, _("Indexed load:")); KadInfoList->SetItem(next_row++, 1, CFormat(wxT("%d")) % theApp->GetKadIndexedLoad()); KadInfoList->InsertItem(next_row, _("Average Users:")); KadInfoList->SetItem(next_row, 1, CastItoIShort(theApp->GetKadUsers())); ++next_row; KadInfoList->InsertItem(next_row, _("Average Files:")); KadInfoList->SetItem(next_row, 1, CastItoIShort(theApp->GetKadFiles())); } } else { // No data KadInfoList->SetItem(next_row, 1, _("Not running")); } // Fit the width of the columns KadInfoList->SetColumnWidth(0, -1); KadInfoList->SetColumnWidth(1, -1); }
bool CClientList::IncomingBuddy(Kademlia::CContact* contact, Kademlia::CUInt128* buddyID) { uint32_t nContactIP = wxUINT32_SWAP_ALWAYS(contact->GetIPAddress()); //If aMule already knows this client, abort this.. It could cause conflicts. //Although the odds of this happening is very small, it could still happen. if (FindClientByIP(nContactIP, contact->GetTCPPort())) { return false; } else if (IsKadFirewallCheckIP(nContactIP)) { // doing a kad firewall check with this IP, abort AddDebugLogLineN(logKadMain, wxT("Kad TCP firewallcheck / Buddy request collision for IP ") + Uint32toStringIP(nContactIP)); return false; } if (theApp->GetPublicIP() == nContactIP && thePrefs::GetPort() == contact->GetTCPPort()) { return false; // don't connect ourself } //Add client to the lists to be processed. CUpDownClient* pNewClient = new CUpDownClient(contact->GetTCPPort(), contact->GetIPAddress(), 0, 0, NULL, false, true ); pNewClient->SetKadPort(contact->GetUDPPort()); pNewClient->SetKadState(KS_INCOMING_BUDDY); byte ID[16]; contact->GetClientID().ToByteArray(ID); pNewClient->SetUserHash(CMD4Hash(ID)); buddyID->ToByteArray(ID); pNewClient->SetBuddyID(ID); AddToKadList(pNewClient); AddClient(pNewClient); return true; }
void CClientList::RequestBuddy(Kademlia::CContact* contact, uint8_t connectOptions) { uint32_t nContactIP = wxUINT32_SWAP_ALWAYS(contact->GetIPAddress()); // Don't connect to ourself if (theApp->GetPublicIP() == nContactIP && thePrefs::GetPort() == contact->GetTCPPort()) { return; } CUpDownClient* pNewClient = FindClientByIP(nContactIP, contact->GetTCPPort()); if (!pNewClient) { pNewClient = new CUpDownClient(contact->GetTCPPort(), contact->GetIPAddress(), 0, 0, NULL, false, true ); } else if (pNewClient->GetKadState() != KS_NONE) { return; // already busy with this client in some way (probably fw stuff), don't mess with it } else if (IsKadFirewallCheckIP(nContactIP)) { // doing a kad firewall check with this IP, abort AddDebugLogLineN(logKadMain, wxT("Kad TCP firewallcheck / Buddy request collision for IP ") + Uint32toStringIP(nContactIP)); return; } //Add client to the lists to be processed. pNewClient->SetKadPort(contact->GetUDPPort()); pNewClient->SetKadState(KS_QUEUED_BUDDY); uint8_t ID[16]; contact->GetClientID().ToByteArray(ID); pNewClient->SetUserHash(CMD4Hash(ID)); pNewClient->SetConnectOptions(connectOptions, true, false); AddToKadList(pNewClient); //This method checks if this is a dup already. AddClient(pNewClient); }
void CClientList::Process() { const uint32 cur_tick = ::GetTickCount(); if (m_dwLastBannCleanUp + BAN_CLEANUP_TIME < cur_tick) { m_dwLastBannCleanUp = cur_tick; ClientMap::iterator it = m_bannedList.begin(); while ( it != m_bannedList.end() ) { if ( it->second + CLIENTBANTIME < cur_tick ) { ClientMap::iterator tmp = it++; m_bannedList.erase( tmp ); theStats::RemoveBannedClient(); } else { ++it; } } } if ( m_dwLastTrackedCleanUp + TRACKED_CLEANUP_TIME < cur_tick ) { m_dwLastTrackedCleanUp = cur_tick; std::map<uint32, CDeletedClient*>::iterator it = m_trackedClientsList.begin(); while ( it != m_trackedClientsList.end() ) { std::map<uint32, CDeletedClient*>::iterator cur_src = it++; if ( cur_src->second->m_dwInserted + KEEPTRACK_TIME < cur_tick ) { delete cur_src->second; m_trackedClientsList.erase( cur_src ); } } } //We need to try to connect to the clients in m_KadList //If connected, remove them from the list and send a message back to Kad so we can send a ACK. //If we don't connect, we need to remove the client.. //The sockets timeout should delete this object. // buddy is just a flag that is used to make sure we are still connected or connecting to a buddy. buddyState buddy = Disconnected; CClientRefSet::iterator current_it = m_KadSources.begin(); while (current_it != m_KadSources.end()) { CUpDownClient* cur_client = current_it->GetClient(); ++current_it; // Won't be used anymore till while loop if( !Kademlia::CKademlia::IsRunning() ) { //Clear out this list if we stop running Kad. //Setting the Kad state to KS_NONE causes it to be removed in the switch below. cur_client->SetKadState(KS_NONE); } switch (cur_client->GetKadState()) { case KS_QUEUED_FWCHECK: case KS_QUEUED_FWCHECK_UDP: //Another client asked us to try to connect to them to check their firewalled status. cur_client->TryToConnect(true); break; case KS_CONNECTING_FWCHECK: //Ignore this state as we are just waiting for results. break; case KS_FWCHECK_UDP: case KS_CONNECTING_FWCHECK_UDP: // We want a UDP firewallcheck from this client and are just waiting to get connected to send the request break; case KS_CONNECTED_FWCHECK: //We successfully connected to the client. //We now send a ack to let them know. if (cur_client->GetKadVersion() >= 7) { // The result is now sent per TCP instead of UDP, because this will fail if our intern port is unreachable. // But we want the TCP testresult regardless if UDP is firewalled, the new UDP state and test takes care of the rest wxASSERT(cur_client->IsConnected()); AddDebugLogLineN(logLocalClient, wxT("Local Client: OP_KAD_FWTCPCHECK_ACK to ") + Uint32toStringIP(cur_client->GetIP())); CPacket *packet = new CPacket(OP_KAD_FWTCPCHECK_ACK, 0, OP_EMULEPROT); cur_client->SafeSendPacket(packet); } else { AddDebugLogLineN(logClientKadUDP, wxT("KadFirewalledAckRes to ") + Uint32_16toStringIP_Port(cur_client->GetIP(), cur_client->GetKadPort())); Kademlia::CKademlia::GetUDPListener()->SendNullPacket(KADEMLIA_FIREWALLED_ACK_RES, wxUINT32_SWAP_ALWAYS(cur_client->GetIP()), cur_client->GetKadPort(), 0, NULL); } //We are done with this client. Set Kad status to KS_NONE and it will be removed in the next cycle. cur_client->SetKadState(KS_NONE); break; case KS_INCOMING_BUDDY: //A firewalled client wants us to be his buddy. //If we already have a buddy, we set Kad state to KS_NONE and it's removed in the next cycle. //If not, this client will change to KS_CONNECTED_BUDDY when it connects. if( m_nBuddyStatus == Connected ) { cur_client->SetKadState(KS_NONE); } break; case KS_QUEUED_BUDDY: //We are firewalled and want to request this client to be a buddy. //But first we check to make sure we are not already trying another client. //If we are not already trying. We try to connect to this client. //If we are already connected to a buddy, we set this client to KS_NONE and it's removed next cycle. //If we are trying to connect to a buddy, we just ignore as the one we are trying may fail and we can then try this one. if( m_nBuddyStatus == Disconnected ) { buddy = Connecting; m_nBuddyStatus = Connecting; cur_client->SetKadState(KS_CONNECTING_BUDDY); cur_client->TryToConnect(true); Notify_ServerUpdateED2KInfo(); } else { if( m_nBuddyStatus == Connected ) { cur_client->SetKadState(KS_NONE); } } break; case KS_CONNECTING_BUDDY: //We are trying to connect to this client. //Although it should NOT happen, we make sure we are not already connected to a buddy. //If we are we set to KS_NONE and it's removed next cycle. //But if we are not already connected, make sure we set the flag to connecting so we know //things are working correctly. if( m_nBuddyStatus == Connected ) { cur_client->SetKadState(KS_NONE); } else { wxASSERT( m_nBuddyStatus == Connecting ); buddy = Connecting; } break; case KS_CONNECTED_BUDDY: //A potential connected buddy client wanting to me in the Kad network //We set our flag to connected to make sure things are still working correctly. buddy = Connected; //If m_nBuddyStatus is not connected already, we set this client as our buddy! if( m_nBuddyStatus != Connected ) { m_pBuddy.Link(cur_client CLIENT_DEBUGSTRING("CClientList::Process KS_CONNECTED_BUDDY m_pBuddy.Link")); m_nBuddyStatus = Connected; Notify_ServerUpdateED2KInfo(); } if( m_pBuddy.GetClient() == cur_client && theApp->IsFirewalled() && cur_client->SendBuddyPingPong() ) { cur_client->SendBuddyPing(); } break; default: RemoveFromKadList(cur_client); } } //We either never had a buddy, or lost our buddy.. if( buddy == Disconnected ) { if( m_nBuddyStatus != Disconnected || m_pBuddy.IsLinked() ) { if( Kademlia::CKademlia::IsRunning() && theApp->IsFirewalled() && Kademlia::CUDPFirewallTester::IsFirewalledUDP(true) ) { //We are a lowID client and we just lost our buddy. //Go ahead and instantly try to find a new buddy. Kademlia::CKademlia::GetPrefs()->SetFindBuddy(); } m_pBuddy.Unlink(); m_nBuddyStatus = Disconnected; Notify_ServerUpdateED2KInfo(); } } if ( Kademlia::CKademlia::IsConnected() ) { // we only need a buddy if direct callback is not available if(Kademlia::CKademlia::IsFirewalled() && Kademlia::CUDPFirewallTester::IsFirewalledUDP(true)) { // TODO: Kad buddies won't work with RequireCrypt, so it is disabled for now, but should (and will) // be fixed in later version // Update: buddy connections themselves support obfuscation properly since eMule 0.49a and aMule SVN 2008-05-09 // (this makes it work fine if our buddy uses require crypt), however callback requests don't support it yet so we // wouldn't be able to answer callback requests with RequireCrypt, protocolchange intended for eMule 0.49b if(m_nBuddyStatus == Disconnected && Kademlia::CKademlia::GetPrefs()->GetFindBuddy() && !thePrefs::IsClientCryptLayerRequired()) { AddDebugLogLineN(logKadMain, wxT("Starting BuddySearch")); //We are a firewalled client with no buddy. We have also waited a set time //to try to avoid a false firewalled status.. So lets look for a buddy.. if (!Kademlia::CSearchManager::PrepareLookup(Kademlia::CSearch::FINDBUDDY, true, Kademlia::CUInt128(true) ^ (Kademlia::CKademlia::GetPrefs()->GetKadID()))) { //This search ID was already going. Most likely reason is that //we found and lost our buddy very quickly and the last search hadn't //had time to be removed yet. Go ahead and set this to happen again //next time around. Kademlia::CKademlia::GetPrefs()->SetFindBuddy(); } } } else { if (m_pBuddy.IsLinked()) { //Lets make sure that if we have a buddy, they are firewalled! //If they are also not firewalled, then someone must have fixed their firewall or stopped saturating their line.. //We just set the state of this buddy to KS_NONE and things will be cleared up with the next cycle. if( !m_pBuddy.HasLowID() ) { m_pBuddy.GetClient()->SetKadState(KS_NONE); } } } } else { if (m_pBuddy.IsLinked()) { //We are not connected anymore. Just set this buddy to KS_NONE and things will be cleared out on next cycle. m_pBuddy.GetClient()->SetKadState(KS_NONE); } } CleanUpClientList(); ProcessDirectCallbackList(); }