Fix compile error
[amule.git] / src / ServerSocket.cpp
blobf561ed67ed71330df2acb6f6a15e14a5fdb0a6f7
1 //
2 // This file is part of the aMule Project.
3 //
4 // Copyright (c) 2003-2011 aMule Team ( admin@amule.org / http://www.amule.org )
5 // Copyright (c) 2002-2011 Merkur ( devs@emule-project.net / http://www.emule-project.net )
6 //
7 // Any parts of this program derived from the xMule, lMule or eMule project,
8 // or contributed by third-party developers are copyrighted by their
9 // respective authors.
11 // This program is free software; you can redistribute it and/or modify
12 // it under the terms of the GNU General Public License as published by
13 // the Free Software Foundation; either version 2 of the License, or
14 // (at your option) any later version.
16 // This program is distributed in the hope that it will be useful,
17 // but WITHOUT ANY WARRANTY; without even the implied warranty of
18 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 // GNU General Public License for more details.
21 // You should have received a copy of the GNU General Public License
22 // along with this program; if not, write to the Free Software
23 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
26 #include "ServerSocket.h" // Interface declarations
28 #include <protocol/Protocols.h>
29 #include <common/EventIDs.h>
30 #include <tags/ServerTags.h>
32 #include <wx/tokenzr.h>
34 #include "Packet.h" // Needed for CPacket
35 #include "updownclient.h" // Needed for CUpDownClient
36 #include "ClientList.h" // Needed for CClientList
37 #include "MemFile.h" // Needed for CMemFile
38 #include "PartFile.h" // Needed for CPartFile
39 #include "SearchList.h" // Needed for CSearchList
40 #include "Preferences.h" // Needed for CPreferences
41 #include "DownloadQueue.h" // Needed for CDownloadQueue
42 #include "ServerList.h" // Needed for CServerList
43 #include "Server.h" // Needed for CServer
44 #include "amule.h" // Needed for theApp
45 #include "Statistics.h" // Needed for theStats
46 #include "AsyncDNS.h" // Needed for CAsyncDNS
47 #include "Logger.h"
48 #include <common/Format.h>
49 #include "IPFilter.h"
50 #include "GuiEvents.h" // Needed for Notify_*
54 //------------------------------------------------------------------------------
55 // CServerSocketHandler
56 //------------------------------------------------------------------------------
58 //------------------------------------------------------------------------------
59 // CServerSocketHandler
60 //------------------------------------------------------------------------------
63 class CServerSocketHandler: public wxEvtHandler
65 public:
66 CServerSocketHandler() {};
68 public:
69 private:
70 void ServerSocketHandler(wxSocketEvent& event);
71 DECLARE_EVENT_TABLE()
75 BEGIN_EVENT_TABLE(CServerSocketHandler, wxEvtHandler)
76 EVT_SOCKET(ID_SERVERSOCKET_EVENT, CServerSocketHandler::ServerSocketHandler)
77 END_EVENT_TABLE()
79 void CServerSocketHandler::ServerSocketHandler(wxSocketEvent& event)
81 CServerSocket *socket = dynamic_cast<CServerSocket *>(event.GetSocket());
82 wxASSERT(socket);
83 if (!socket) {
84 return;
87 if (socket->IsDestroying()) {
88 return;
91 switch(event.GetSocketEvent()) {
92 case wxSOCKET_CONNECTION:
93 socket->OnConnect(wxSOCKET_NOERROR);
94 break;
95 case wxSOCKET_LOST:
96 socket->OnError(socket->LastError());
97 break;
98 case wxSOCKET_INPUT:
99 socket->OnReceive(wxSOCKET_NOERROR);
100 break;
101 case wxSOCKET_OUTPUT:
102 socket->OnSend(wxSOCKET_NOERROR);
103 break;
104 default:
105 wxFAIL;
106 break;
113 // There can be only one. :)
115 static CServerSocketHandler g_serverSocketHandler;
118 //------------------------------------------------------------------------------
119 // CServerSocket
120 //------------------------------------------------------------------------------
122 CServerSocket::CServerSocket(CServerConnect* in_serverconnect, const CProxyData *ProxyData)
124 CEMSocket(ProxyData)
126 serverconnect = in_serverconnect;
127 connectionstate = 0;
128 cur_server = 0;
129 info.Clear();
130 m_bIsDeleting = false;
132 SetEventHandler(g_serverSocketHandler, ID_SERVERSOCKET_EVENT);
134 SetNotify(
135 wxSOCKET_CONNECTION_FLAG |
136 wxSOCKET_INPUT_FLAG |
137 wxSOCKET_OUTPUT_FLAG |
138 wxSOCKET_LOST_FLAG);
139 Notify(true);
141 m_dwLastTransmission = 0;
142 m_IsSolving = false;
143 m_bNoCrypt = false;
146 CServerSocket::~CServerSocket()
148 // remove event handler...
149 SetNotify(0);
150 Notify(FALSE);
152 if (cur_server) {
153 delete cur_server;
155 cur_server = NULL;
159 void CServerSocket::OnConnect(int nErrorCode)
161 switch (nErrorCode) {
162 case wxSOCKET_NOERROR:
163 if (cur_server->HasDynIP()) {
164 uint32 server_ip = GetPeerInt();
165 cur_server->SetID(server_ip);
166 // GetServerByAddress may return NULL, so we must test!
167 // This was the reason why amule would crash when trying to
168 // connect in wxWidgets 2.5.2
169 CServer *pServer = theApp->serverlist->GetServerByAddress(
170 cur_server->GetAddress(), cur_server->GetPort());
171 if (pServer) {
172 pServer->SetID(server_ip);
173 } else {
174 AddDebugLogLineN(logServer, wxT("theApp->serverlist->GetServerByAddress() returned NULL"));
175 return;
178 SetConnectionState(CS_WAITFORLOGIN);
179 break;
181 case wxSOCKET_INVADDR:
182 case wxSOCKET_NOHOST:
183 case wxSOCKET_INVPORT:
184 case wxSOCKET_TIMEDOUT:
185 m_bIsDeleting = true;
186 SetConnectionState(CS_SERVERDEAD);
187 serverconnect->DestroySocket(this);
188 return;
190 case wxSOCKET_IOERR:
191 case wxSOCKET_MEMERR:
192 case wxSOCKET_INVOP:
193 default:
194 m_bIsDeleting = true;
195 SetConnectionState(CS_FATALERROR);
196 serverconnect->DestroySocket(this);
197 return;
203 void CServerSocket::OnReceive(int nErrorCode)
205 if (connectionstate != CS_CONNECTED && !serverconnect->IsConnecting()) {
206 serverconnect->DestroySocket(this);
207 return;
209 CEMSocket::OnReceive(nErrorCode);
210 m_dwLastTransmission = GetTickCount();
213 bool CServerSocket::ProcessPacket(const byte* packet, uint32 size, int8 opcode)
215 try {
216 AddDebugLogLineN( logServer, wxT("Processing Server Packet: ") );
218 switch(opcode) {
219 case OP_SERVERMESSAGE: {
220 /* Kry import of lugdunum 16.40 new features */
221 AddDebugLogLineN( logServer, wxT("Server: OP_SERVERMESSAGE") );
223 theStats::AddDownOverheadServer(size);
224 char* buffer = new char[size-1];
225 memcpy(buffer,&packet[2],size-2);
226 buffer[size-2] = 0;
228 wxString strMessages(char2unicode(buffer));
230 delete[] buffer;
232 // 16.40 servers do not send separate OP_SERVERMESSAGE packets for each line;
233 // instead of this they are sending all text lines with one OP_SERVERMESSAGE packet.
235 wxStringTokenizer token(strMessages,wxT("\r\n"),wxTOKEN_DEFAULT );
237 while (token.HasMoreTokens()) {
238 wxString message = token.GetNextToken();
240 bool bOutputMessage = true;
241 if (message.StartsWith(wxT("server version"))) {
242 wxString strVer = message.Mid(15,64); // truncate string to avoid misuse by servers in showing ads
243 strVer.Trim();
244 CServer* eserver = theApp->serverlist->GetServerByAddress(cur_server->GetAddress(),cur_server->GetPort());
245 if (eserver) {
246 eserver->SetVersion(strVer);
247 Notify_ServerRefresh(eserver);
249 } else if (message.StartsWith(wxT("ERROR"))) {
250 CServer* pServer = theApp->serverlist->GetServerByAddress(cur_server->GetAddress(),cur_server->GetPort());
251 wxString servername;
252 if (pServer) {
253 servername = pServer->GetListName();
254 } else {
255 servername = _("Server");
257 AddLogLineN(CFormat( _("ERROR: %s (%s) - %s") )
258 % servername
259 % Uint32_16toStringIP_Port(cur_server->GetIP(), cur_server->GetPort())
260 % message.Mid(5,message.Len()).Trim(wxT(" :")));
261 bOutputMessage = false;
263 } else if (message.StartsWith(wxT("WARNING"))) {
265 CServer* pServer = theApp->serverlist->GetServerByAddress(cur_server->GetAddress(),cur_server->GetPort());
266 wxString servername;
267 if (pServer) {
268 servername = pServer->GetListName();
269 } else {
270 servername = _("Server");
272 AddLogLineN(CFormat( _("WARNING: %s (%s) - %s") )
273 % servername
274 % Uint32_16toStringIP_Port(cur_server->GetIP(), cur_server->GetPort())
275 % message.Mid(5,message.Len()).Trim(wxT(" :")));
277 bOutputMessage = false;
280 if (message.Find(wxT("[emDynIP: ")) != (-1) && message.Find(wxT("]")) != (-1) && message.Find(wxT("[emDynIP: ")) < message.Find(wxT("]"))){
281 wxString dynip = message.Mid(message.Find(wxT("[emDynIP: "))+10,message.Find(wxT("]")) - (message.Find(wxT("[emDynIP: "))+10));
282 dynip.Trim(wxT(" "));
283 if ( dynip.Length() && dynip.Length() < 51){
284 CServer* eserver = theApp->serverlist->GetServerByAddress(cur_server->GetAddress(),cur_server->GetPort());
285 if (eserver){
286 eserver->SetDynIP(dynip);
287 cur_server->SetDynIP(dynip);
288 Notify_ServerRefresh(eserver);
293 if (bOutputMessage) {
294 theApp->AddServerMessageLine(message);
297 break;
299 case OP_IDCHANGE: {
300 AddDebugLogLineN(logServer, wxT("Server: OP_IDCHANGE"));
302 theStats::AddDownOverheadServer(size);
304 if (size < 4 /* uint32 (ID)*/) {
305 throw wxString(wxT("Corrupt or invalid loginanswer from server received"));
308 CMemFile data(packet, size);
310 uint32 new_id = data.ReadUInt32();
312 // save TCP flags in 'cur_server'
313 wxASSERT(cur_server);
314 CServer* pServer = NULL;
315 if (cur_server) {
316 uint32 ConnPort = 0;
317 uint32 rport = cur_server->GetConnPort();
318 pServer = theApp->serverlist->GetServerByAddress(cur_server->GetAddress(), rport);
319 if (size >= 4+4 /* uint32 (ID) + uint32 (TCP flags)*/) {
320 cur_server->SetTCPFlags(data.ReadUInt32());
321 if (size >= 4+4+4 /* uint32 (ID) + uint32 (TCP flags) + uint32 (aux port) */) {
322 // aux port login : we should use the 'standard' port of this server to advertize to other clients
323 ConnPort = data.ReadUInt32();
324 cur_server->SetPort(ConnPort);
325 if (cur_server->GetAuxPortsList().IsEmpty()) {
326 cur_server->SetAuxPortsList(CFormat(wxT("%u")) % rport);
329 } else {
330 cur_server->SetTCPFlags(0);
332 // copy TCP flags into the server in the server list
333 if (pServer) {
334 pServer->SetTCPFlags(cur_server->GetTCPFlags());
335 if (ConnPort) {
336 pServer->SetPort(ConnPort);
337 if (pServer->GetAuxPortsList().IsEmpty()) {
338 pServer->SetAuxPortsList(CFormat(wxT("%u")) % pServer->GetConnPort());
340 Notify_ServerRefresh(pServer);
341 Notify_ServerUpdateED2KInfo();
346 uint32 dwServerReportedIP = 0;
347 if (size >= 4 + 4 + 4 + 4 + 4 /* All of the above + reported ip + obfuscation port */) {
348 dwServerReportedIP = data.ReadUInt32();
349 if (::IsLowID(dwServerReportedIP)){
350 wxFAIL;
351 dwServerReportedIP = 0;
353 wxASSERT( dwServerReportedIP == new_id || ::IsLowID(new_id) );
354 uint32 dwObfuscationTCPPort = data.ReadUInt32();
355 if (dwObfuscationTCPPort != 0) {
356 if (cur_server != NULL) {
357 cur_server->SetObfuscationPortTCP(dwObfuscationTCPPort);
359 if (pServer != NULL) {
360 pServer->SetObfuscationPortTCP(dwObfuscationTCPPort);
365 if (new_id == 0) {
366 uint8 state = thePrefs::GetSmartIdState();
367 if ( state > 0 ) {
368 state++;
369 if(state > 3) {
370 thePrefs::SetSmartIdState(0);
371 } else {
372 thePrefs::SetSmartIdState(state);
375 break;
377 if(thePrefs::GetSmartIdCheck()) {
378 if (!IsLowID(new_id)) {
379 thePrefs::SetSmartIdState(1);
380 } else {
381 uint8 state = thePrefs::GetSmartIdState();
382 if ( state > 0 ) {
383 state++;
384 if(state > 3) {
385 thePrefs::SetSmartIdState(0);
386 } else {
387 thePrefs::SetSmartIdState(state);
389 break;
394 // we need to know our client when sending our shared files (done indirectly on SetConnectionState)
396 serverconnect->SetClientID(new_id);
398 if (::IsLowID(new_id) && dwServerReportedIP != 0) {
399 theApp->SetPublicIP(dwServerReportedIP);
402 if (connectionstate != CS_CONNECTED) {
403 AddDebugLogLineN(logServer, wxT("Connected"));
405 SetConnectionState(CS_CONNECTED);
406 theApp->OnlineSig(); // Added By Bouc7
409 theApp->ShowConnectionState();
411 AddLogLineN(CFormat(_("New clientid is %u")) % new_id);
412 if (::IsLowID(new_id)) {
413 AddLogLineC(_("WARNING: You have received Low-ID!"));
414 AddLogLineN(_("\tMost likely this is because you're behind a firewall or router."));
415 AddLogLineN(_("\tFor more information, please refer to http://wiki.amule.org"));
418 theApp->downloadqueue->ResetLocalServerRequests();
419 break;
421 case OP_SEARCHRESULT: {
422 AddDebugLogLineN(logServer, wxT("Server: OP_SEARCHRESULT"));
424 theStats::AddDownOverheadServer(size);
425 CServer* cur_srv = (serverconnect) ?
426 serverconnect->GetCurrentServer() : NULL;
427 theApp->searchlist->ProcessSearchAnswer(
428 packet,
429 size,
430 true /*(cur_srv && cur_srv->GetUnicodeSupport())*/,
431 cur_srv ? cur_srv->GetIP() : 0,
432 cur_srv ? cur_srv->GetPort() : 0);
433 theApp->searchlist->LocalSearchEnd();
434 break;
436 case OP_FOUNDSOURCES_OBFU:
437 case OP_FOUNDSOURCES: {
438 AddDebugLogLineN(logServer, CFormat(wxT("ServerMsg - OP_FoundSources; sources = %u")) % packet[16]);
439 theStats::AddDownOverheadServer(size);
440 CMemFile sources(packet,size);
441 CMD4Hash fileid = sources.ReadHash();
442 if (CPartFile* file = theApp->downloadqueue->GetFileByID(fileid)) {
443 file->AddSources(sources, cur_server->GetIP(), cur_server->GetPort(), SF_LOCAL_SERVER, (opcode == OP_FOUNDSOURCES_OBFU));
444 } else {
445 AddDebugLogLineN(logServer, wxT("Sources received for unknown file: ") + fileid.Encode());
447 break;
449 case OP_SERVERSTATUS: {
450 AddDebugLogLineN(logServer, wxT("Server: OP_SERVERSTATUS"));
451 // FIXME some statuspackets have a different size -> why? structur?
452 if (size < 8) {
453 throw wxString(wxT("Invalid server status packet"));
455 CServer* update = theApp->serverlist->GetServerByAddress(cur_server->GetAddress(), cur_server->GetPort());
456 if (update) {
457 CMemFile data(packet, size);
458 update->SetUserCount(data.ReadUInt32());
459 update->SetFileCount(data.ReadUInt32());
460 Notify_ServerRefresh( update );
461 theApp->ShowUserCount();
463 break;
465 // Cleaned.
466 case OP_SERVERIDENT: {
467 AddDebugLogLineN(logServer, wxT("Server: OP_SERVERIDENT"));
469 theStats::AddDownOverheadServer(size);
470 if (size<38) {
471 AddLogLineN(_("Unknown server info received! - too short"));
472 // throw wxString(wxT("Unknown server info received!"));
473 break;
475 CServer* update = theApp->serverlist->GetServerByAddress(cur_server->GetAddress(),cur_server->GetPort());
476 if (update) {
477 CMemFile data(packet,size);
478 CMD4Hash hash = data.ReadHash();
479 if (RawPeekUInt32(hash.GetHash()) == 0x2A2A2A2A){ // No endian problem here
480 const wxString& rstrVersion = update->GetVersion();
481 if (!rstrVersion.IsEmpty()) {
482 update->SetVersion(wxT("eFarm ") + rstrVersion);
483 } else {
484 update->SetVersion(wxT("eFarm"));
487 // Unused
488 /*uint32 nServerIP = */data.ReadUInt32();
489 /*uint16 nServerPort = */data.ReadUInt16();
491 uint32 nTags = data.ReadUInt32();
492 for (uint32 i = 0; i < nTags; i++){
493 CTag tag(data, update->GetUnicodeSupport());
494 if (tag.GetNameID() == ST_SERVERNAME){
495 update->SetListName(tag.GetStr());
496 } else if (tag.GetNameID() == ST_DESCRIPTION){
497 update->SetDescription(tag.GetStr());
498 } // No more known tags from server
501 theApp->ShowConnectionState();
502 Notify_ServerRefresh(update);
504 break;
506 // tecxx 1609 2002 - add server's serverlist to own serverlist
507 case OP_SERVERLIST: {
508 AddDebugLogLineN(logServer, wxT("Server: OP_SERVERLIST"));
510 CMemFile* servers = new CMemFile(packet,size);
511 uint8 count = servers->ReadUInt8();
512 if (((int32)(count*6 + 1) > size)) {
513 count = 0;
515 int addcount = 0;
516 while(count) {
517 uint32 ip = servers->ReadUInt32();
518 uint16 port = servers->ReadUInt16();
519 CServer* srv = new CServer(
520 port , // Port
521 Uint32toStringIP(ip)); // Ip
522 srv->SetListName(srv->GetFullIP());
523 if (!theApp->AddServer(srv)) {
524 delete srv;
525 } else {
526 addcount++;
528 count--;
530 delete servers;
531 if (addcount) {
532 AddLogLineN(CFormat(wxPLURAL("Received %d new server", "Received %d new servers", addcount)) % addcount);
534 theApp->serverlist->SaveServerMet();
535 AddLogLineN(_("Saving of server-list completed."));
536 break;
538 case OP_CALLBACKREQUESTED: {
539 AddDebugLogLineN(logServer, wxT("Server: OP_CALLBACKREQUESTED"));
541 theStats::AddDownOverheadServer(size);
542 if (size >= 6) {
543 CMemFile data(packet,size);
544 uint32 dwIP = data.ReadUInt32();
545 uint16 nPort = data.ReadUInt16();
547 uint8 byCryptOptions = 0;
548 CMD4Hash achUserHash;
549 if (size >= 23){
550 byCryptOptions = data.ReadUInt8();;
551 achUserHash = data.ReadHash();
554 CUpDownClient* client = theApp->clientlist->FindClientByIP(dwIP,nPort);
556 if (!client) {
557 client = new CUpDownClient(nPort,dwIP,0,0,0, true, true);
558 theApp->clientlist->AddClient(client);
560 if (size >= 23 && client->HasValidHash()){
561 if (client->GetUserHash() != achUserHash){
562 AddDebugLogLineN(logServer, wxT("Reported Userhash from OP_CALLBACKREQUESTED differs with our stored hash"));
563 // disable crypt support since we dont know which hash is true
564 client->SetCryptLayerRequest(false);
565 client->SetCryptLayerSupport(false);
566 client->SetCryptLayerRequires(false);
567 } else {
568 client->SetConnectOptions(byCryptOptions, true, false);
570 } else if (size >= 23) {
571 client->SetUserHash(achUserHash);
572 client->SetConnectOptions(byCryptOptions, true, false);
575 client->TryToConnect();
577 break;
579 case OP_CALLBACK_FAIL: {
580 AddDebugLogLineN(logServer, wxT("Server: OP_CALLBACK_FAIL"));
581 break;
583 case OP_REJECT: {
584 AddDebugLogLineN(logServer, wxT("Server: OP_REJECT"));
585 AddLogLineN(_("Server rejected last command"));
586 break;
588 default:
589 AddDebugLogLineN(logPacketErrors, CFormat(wxT("Unknown server packet with OPcode %x")) % opcode);
591 return true;
592 } catch (const CInvalidPacket& e) {
593 AddLogLineN(CFormat( _("Bogus packet received from server: %s") ) % e.what());
594 } catch (const CEOFException& e) {
595 AddLogLineN(CFormat( _("Bogus packet received from server: %s") ) % e.what());
596 } catch (const wxString& error) {
597 AddLogLineN(CFormat( _("Unhandled error while processing packet from server: %s") ) % error);
600 // Don't disconnect because of wrong sources.
601 if (opcode==OP_SEARCHRESULT || opcode==OP_FOUNDSOURCES) {
602 return true;
605 SetConnectionState(CS_DISCONNECTED);
606 return false;
609 void CServerSocket::ConnectToServer(CServer* server, bool bNoCrypt)
611 AddDebugLogLineN(logServer, wxT("Trying to connect"));
613 if (cur_server){
614 wxFAIL;
615 delete cur_server;
616 cur_server = NULL;
619 cur_server = new CServer(server);
621 m_bNoCrypt = bNoCrypt;
623 SetConnectionState(CS_CONNECTING);
625 info = cur_server->GetListName();
627 // This must be used if we want to reverse-check the addr of the server
628 if (cur_server->HasDynIP() || !cur_server->GetIP()) {
629 m_IsSolving = true;
630 // Send it to solving thread.
631 CAsyncDNS* dns = new CAsyncDNS(server->GetAddress(), DNS_SERVER_CONNECT, theApp, this);
633 if ( dns->Create() == wxTHREAD_NO_ERROR ) {
634 if ( dns->Run() != wxTHREAD_NO_ERROR ) {
635 dns->Delete();
636 AddLogLineN(CFormat( _("Cannot create DNS solving thread for connecting to %s") ) % cur_server->GetAddress());
638 } else {
639 dns->Delete();
640 AddLogLineN(CFormat( _("Cannot create DNS solving thread for connecting to %s") ) % cur_server->GetAddress());
642 } else {
643 // Nothing to solve, we already have the IP
644 OnHostnameResolved(cur_server->GetIP());
649 void CServerSocket::OnError(int DEBUG_ONLY(nErrorCode))
651 AddDebugLogLineN(logServer, CFormat(wxT("Error in serversocket: %s(%s:%i): %u"))
652 % cur_server->GetListName() % cur_server->GetFullIP() % cur_server->GetPort() % nErrorCode);
653 SetConnectionState(CS_DISCONNECTED);
657 bool CServerSocket::PacketReceived(CPacket* packet)
659 AddDebugLogLineN(logServer, CFormat(wxT("Server: Packet Received: Prot %x, Opcode %x, Length %u")) % packet->GetProtocol() % packet->GetOpCode() % packet->GetPacketSize());
661 if (packet->GetProtocol() == OP_PACKEDPROT) {
662 if (!packet->UnPackPacket(250000)){
663 AddDebugLogLineN(logZLib, CFormat(wxT("Failed to decompress server TCP packet: protocol=0x%02x opcode=0x%02x size=%u"))
664 % packet->GetProtocol() % packet->GetOpCode() % packet->GetPacketSize());
665 theStats::AddDownOverheadServer(packet->GetPacketSize());
666 return true;
669 packet->SetProtocol(OP_EDONKEYPROT);
672 if (packet->GetProtocol() == OP_EDONKEYPROT) {
673 ProcessPacket(packet->GetDataBuffer(), packet->GetPacketSize(), packet->GetOpCode());
674 } else {
675 AddDebugLogLineN(logServer, CFormat(wxT("Received server TCP packet with unknown protocol: protocol=0x%02x opcode=0x%02x size=%u"))
676 % packet->GetProtocol() % packet->GetOpCode() % packet->GetPacketSize());
677 theStats::AddDownOverheadServer(packet->GetPacketSize());
680 return true;
684 void CServerSocket::OnClose(int WXUNUSED(nErrorCode))
686 CEMSocket::OnClose(0);
688 switch (connectionstate) {
689 case CS_WAITFORLOGIN: SetConnectionState(CS_SERVERFULL); break;
690 case CS_CONNECTED: SetConnectionState(CS_DISCONNECTED); break;
691 default: SetConnectionState(CS_NOTCONNECTED);
694 serverconnect->DestroySocket(this);
697 void CServerSocket::SetConnectionState(sint8 newstate)
699 connectionstate = newstate;
700 if (newstate < CS_CONNECTING) {
701 serverconnect->ConnectionFailed(this);
702 } else if (newstate == CS_CONNECTED || newstate == CS_WAITFORLOGIN) {
703 if (serverconnect) {
704 serverconnect->ConnectionEstablished(this);
710 void CServerSocket::SendPacket(CPacket* packet, bool delpacket, bool controlpacket, uint32 actualPayloadSize)
712 m_dwLastTransmission = GetTickCount();
713 CEMSocket::SendPacket(packet, delpacket, controlpacket, actualPayloadSize);
717 void CServerSocket::OnHostnameResolved(uint32 ip) {
719 m_IsSolving = false;
720 if (ip) {
721 if (theApp->ipfilter->IsFiltered(ip, true)) {
722 AddLogLineC(CFormat( _("Server IP %s (%s) is filtered. Not connecting.") )
723 % Uint32toStringIP(ip) % cur_server->GetAddress() );
724 OnConnect(wxSOCKET_INVADDR);
725 } else {
726 amuleIPV4Address addr;
727 addr.Hostname(ip);
728 uint16 nPort = 0;
729 wxString useObfuscation;
730 if ( !m_bNoCrypt && thePrefs::IsServerCryptLayerTCPRequested() && cur_server->GetObfuscationPortTCP() != 0 && cur_server->SupportsObfuscationTCP()){
731 nPort = cur_server->GetObfuscationPortTCP();
732 useObfuscation = _("using protocol obfuscation.");
733 SetConnectionEncryption(true, NULL, true);
734 } else {
735 nPort = cur_server->GetConnPort();
736 SetConnectionEncryption(false, NULL, true);
739 addr.Service(nPort);
741 AddLogLineN(CFormat( _("Connecting to %s (%s - %s:%i) %s") )
742 % cur_server->GetListName()
743 % cur_server->GetAddress()
744 % cur_server->GetFullIP()
745 % nPort
746 % useObfuscation
749 AddDebugLogLineN(logServer, CFormat(wxT("Server %s(%s) Port %i"))
750 % cur_server->GetAddress() % Uint32toStringIP(ip) % cur_server->GetConnPort());
751 Connect(addr, false);
753 } else {
754 AddLogLineC(CFormat( _("Could not solve dns for server %s: Unable to connect!") )
755 % cur_server->GetAddress() );
756 OnConnect(wxSOCKET_NOHOST);
760 uint32 CServerSocket::GetServerIP() const
762 return cur_server ? cur_server->GetIP() : 0;
764 // File_checked_for_headers