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.
10//
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.
15//
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.
20//
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
24//
25
26#include "Server.h"		// Interface declarations.
27
28#include <tags/ServerTags.h>
29
30#include "NetworkFunctions.h" // Needed for StringIPtoUint32
31#include "OtherStructs.h"	// Needed for ServerMet_Struct
32#include "amule.h"
33
34CServer::CServer(ServerMet_Struct* in_data)
35{
36	port = in_data->port;
37	ip = in_data->ip;
38
39	Init();
40}
41
42CServer::CServer(uint16 in_port, const wxString i_addr)
43{
44
45	port = in_port;
46	ip = StringIPtoUint32(i_addr);
47
48	Init();
49
50	// GonoszTopi - Init() would clear dynip !
51	// Check that the ip isn't in fact 0.0.0.0
52	if (!ip && !StringIPtoUint32( i_addr, ip ) ) {
53		// If ip == 0, the address is a hostname
54		dynip = i_addr;
55	}
56}
57
58
59// copy constructor
60CServer::CServer(CServer* pOld) : CECID(pOld->ECID())
61{
62	wxASSERT(pOld != NULL);
63
64	TagPtrList::iterator it = pOld->m_taglist.begin();
65	for ( ; it != pOld->m_taglist.end(); ++it ) {
66		m_taglist.push_back((*it)->CloneTag());
67	}
68	port = pOld->port;
69	ip = pOld->ip;
70	realport = pOld->realport;
71	staticservermember=pOld->IsStaticMember();
72	tagcount = pOld->tagcount;
73	ipfull = pOld->ipfull;
74	files = pOld->files;
75	users = pOld->users;
76	preferences = pOld->preferences;
77	ping = pOld->ping;
78	failedcount = pOld->failedcount;
79	lastpinged = pOld->lastpinged;
80	lastpingedtime = pOld->lastpingedtime;
81	m_dwRealLastPingedTime = pOld->m_dwRealLastPingedTime;
82	description = pOld->description;
83	listname = pOld->listname;
84	dynip = pOld->dynip;
85	maxusers = pOld->maxusers;
86	m_strVersion = pOld->m_strVersion;
87	m_uTCPFlags = pOld->m_uTCPFlags;
88	m_uUDPFlags = pOld->m_uUDPFlags;
89	challenge = pOld->challenge;
90	softfiles = pOld->softfiles;
91	hardfiles = pOld->hardfiles;
92	m_uDescReqChallenge = pOld->m_uDescReqChallenge;
93	m_uLowIDUsers = pOld->m_uLowIDUsers;
94	lastdescpingedcout = pOld->lastdescpingedcout;
95	m_auxPorts = pOld->m_auxPorts;
96	m_dwServerKeyUDP = pOld->m_dwServerKeyUDP;
97	m_bCryptPingReplyPending = pOld->m_bCryptPingReplyPending;
98	m_dwIPServerKeyUDP = pOld->m_dwIPServerKeyUDP;
99	m_nObfuscationPortTCP = pOld->m_nObfuscationPortTCP;
100	m_nObfuscationPortUDP = pOld->m_nObfuscationPortUDP;
101}
102
103CServer::~CServer()
104{
105	deleteTagPtrListEntries(&m_taglist);
106	m_taglist.clear();
107}
108
109void CServer::Init() {
110
111	ipfull = Uint32toStringIP(ip);
112
113	realport = 0;
114	tagcount = 0;
115	files = 0;
116	users = 0;
117	preferences = 0;
118	ping = 0;
119	description.Clear();
120	listname.Clear();
121	dynip.Clear();
122	failedcount = 0;
123	lastpinged = 0;
124	lastpingedtime = 0;
125	m_dwRealLastPingedTime = 0;
126	staticservermember=false;
127	maxusers=0;
128	m_uTCPFlags = 0;
129	m_uUDPFlags = 0;
130	challenge = 0;
131	softfiles = 0;
132	hardfiles = 0;
133	m_strVersion = _("Unknown");
134	m_uLowIDUsers = 0;
135	m_uDescReqChallenge = 0;
136	lastdescpingedcout = 0;
137	m_auxPorts.Clear();
138	m_lastdnssolve = 0;
139	m_dnsfailure = false;
140
141	m_dwServerKeyUDP = 0;
142	m_bCryptPingReplyPending = false;
143	m_dwIPServerKeyUDP = 0;
144	m_nObfuscationPortTCP = 0;
145	m_nObfuscationPortUDP = 0;
146
147}
148
149
150bool CServer::AddTagFromFile(CFileDataIO* servermet)
151{
152	if (servermet == NULL) {
153		return false;
154	}
155
156	CTag tag(*servermet, true);
157
158	switch(tag.GetNameID()){
159	case ST_SERVERNAME:
160		if (listname.IsEmpty()) {
161			listname = tag.GetStr();
162		}
163		break;
164
165	case ST_DESCRIPTION:
166		if (description.IsEmpty()) {
167			description = tag.GetStr();
168		}
169		break;
170
171	case ST_PREFERENCE:
172		preferences = tag.GetInt();
173		break;
174
175	case ST_PING:
176		ping = tag.GetInt();
177		break;
178
179	case ST_DYNIP:
180		if (dynip.IsEmpty()) {
181			dynip = tag.GetStr();
182		}
183		break;
184
185	case ST_FAIL:
186		failedcount = tag.GetInt();
187		break;
188
189	case ST_LASTPING:
190		lastpinged = tag.GetInt();
191		break;
192
193	case ST_MAXUSERS:
194		maxusers = tag.GetInt();
195		break;
196
197	case ST_SOFTFILES:
198		softfiles = tag.GetInt();
199		break;
200
201	case ST_HARDFILES:
202		hardfiles = tag.GetInt();
203		break;
204
205	case ST_VERSION:
206		if (tag.IsStr()) {
207			// m_strVersion defaults to _("Unknown"), so check for that as well
208			if ((m_strVersion.IsEmpty()) || (m_strVersion == _("Unknown"))) {
209				m_strVersion = tag.GetStr();
210			}
211		} else if (tag.IsInt()) {
212			m_strVersion = CFormat(wxT("%u.%u")) % (tag.GetInt() >> 16) % (tag.GetInt() & 0xFFFF);
213		} else {
214			wxFAIL;
215		}
216		break;
217
218	case ST_UDPFLAGS:
219		m_uUDPFlags = tag.GetInt();
220		break;
221
222	case ST_AUXPORTSLIST:
223		m_auxPorts = tag.GetStr();
224
225		// Some server.mets contain empty ST_AUXPORTSLIST tags
226		if (!m_auxPorts.IsEmpty()) {
227			realport = port;
228			port = StrToULong(m_auxPorts.BeforeFirst(','));
229		}
230		break;
231
232	case ST_LOWIDUSERS:
233		m_uLowIDUsers = tag.GetInt();
234		break;
235
236	case ST_UDPKEY:
237		m_dwServerKeyUDP = tag.GetInt();
238		break;
239
240	case ST_UDPKEYIP:
241		m_dwIPServerKeyUDP = tag.GetInt();
242		break;
243
244	case ST_TCPPORTOBFUSCATION:
245		m_nObfuscationPortTCP = (uint16)tag.GetInt();
246		break;
247
248	case ST_UDPPORTOBFUSCATION:
249		m_nObfuscationPortUDP = (uint16)tag.GetInt();
250		break;
251
252	default:
253		if (!tag.GetName().IsEmpty()) {
254			if (tag.GetName() == wxT("files")) {
255				files = tag.GetInt();
256			} else if (tag.GetName() == wxT("users")) {
257				users = tag.GetInt();
258			}
259		} else {
260			wxFAIL;
261		}
262	}
263
264	return true;
265}
266
267
268void CServer::SetListName(const wxString& newname)
269{
270	listname = newname;
271}
272
273void CServer::SetDescription(const wxString& newname)
274{
275	description = newname;
276}
277
278void CServer::SetID(uint32 newip)
279{
280	wxASSERT(newip);
281	ip = newip;
282	ipfull = Uint32toStringIP(ip);
283}
284
285void CServer::SetDynIP(const wxString& newdynip)
286{
287	dynip = newdynip;
288}
289
290
291void CServer::SetLastDescPingedCount(bool bReset)
292{
293	if (bReset) {
294		lastdescpingedcout = 0;
295	} else {
296		lastdescpingedcout++;
297	}
298}
299
300uint32 CServer::GetServerKeyUDP(bool bForce) const
301{
302	if ((m_dwIPServerKeyUDP != 0 && m_dwIPServerKeyUDP == theApp->GetPublicIP()) || bForce) {
303		return m_dwServerKeyUDP;
304	} else {
305		return 0;
306	}
307}
308
309void CServer::SetServerKeyUDP(uint32 dwServerKeyUDP)
310{
311	wxASSERT( theApp->GetPublicIP() != 0 || dwServerKeyUDP == 0 );
312	m_dwServerKeyUDP = dwServerKeyUDP;
313	m_dwIPServerKeyUDP = theApp->GetPublicIP();
314}
315// File_checked_for_headers
316