1 #include "NativeFeatureIncludes.h"
2 #if _RAKNET_SUPPORT_UDPProxyCoordinator==1
3 
4 #include "UDPProxyCoordinator.h"
5 #include "BitStream.h"
6 #include "UDPProxyCommon.h"
7 #include "RakPeerInterface.h"
8 #include "MessageIdentifiers.h"
9 #include "Rand.h"
10 #include "GetTime.h"
11 #include "UDPForwarder.h"
12 
13 // Larger than the client version
14 static const int DEFAULT_CLIENT_UNRESPONSIVE_PING_TIME=2000;
15 static const int DEFAULT_UNRESPONSIVE_PING_TIME=DEFAULT_CLIENT_UNRESPONSIVE_PING_TIME+1000;
16 
17 using namespace RakNet;
18 
operator <(const DataStructures::MLKeyRef<unsigned short> & inputKey,const UDPProxyCoordinator::ServerWithPing & cls)19 bool operator<( const DataStructures::MLKeyRef<unsigned short> &inputKey, const UDPProxyCoordinator::ServerWithPing &cls ) {return inputKey.Get() < cls.ping;}
operator >(const DataStructures::MLKeyRef<unsigned short> & inputKey,const UDPProxyCoordinator::ServerWithPing & cls)20 bool operator>( const DataStructures::MLKeyRef<unsigned short> &inputKey, const UDPProxyCoordinator::ServerWithPing &cls ) {return inputKey.Get() > cls.ping;}
operator ==(const DataStructures::MLKeyRef<unsigned short> & inputKey,const UDPProxyCoordinator::ServerWithPing & cls)21 bool operator==( const DataStructures::MLKeyRef<unsigned short> &inputKey, const UDPProxyCoordinator::ServerWithPing &cls ) {return inputKey.Get() == cls.ping;}
22 
operator <(const DataStructures::MLKeyRef<UDPProxyCoordinator::SenderAndTargetAddress> & inputKey,const UDPProxyCoordinator::ForwardingRequest * cls)23 bool operator<( const DataStructures::MLKeyRef<UDPProxyCoordinator::SenderAndTargetAddress> &inputKey, const UDPProxyCoordinator::ForwardingRequest *cls )
24 {
25 	return inputKey.Get().senderClientAddress < cls->sata.senderClientAddress ||
26 		(inputKey.Get().senderClientAddress == cls->sata.senderClientAddress && inputKey.Get().targetClientAddress < cls->sata.targetClientAddress);
27 }
operator >(const DataStructures::MLKeyRef<UDPProxyCoordinator::SenderAndTargetAddress> & inputKey,const UDPProxyCoordinator::ForwardingRequest * cls)28 bool operator>( const DataStructures::MLKeyRef<UDPProxyCoordinator::SenderAndTargetAddress> &inputKey, const UDPProxyCoordinator::ForwardingRequest *cls )
29 {
30 	return inputKey.Get().senderClientAddress > cls->sata.senderClientAddress ||
31 		(inputKey.Get().senderClientAddress == cls->sata.senderClientAddress && inputKey.Get().targetClientAddress > cls->sata.targetClientAddress);
32 }
operator ==(const DataStructures::MLKeyRef<UDPProxyCoordinator::SenderAndTargetAddress> & inputKey,const UDPProxyCoordinator::ForwardingRequest * cls)33 bool operator==( const DataStructures::MLKeyRef<UDPProxyCoordinator::SenderAndTargetAddress> &inputKey, const UDPProxyCoordinator::ForwardingRequest *cls )
34 {
35 	return inputKey.Get().senderClientAddress == cls->sata.senderClientAddress && inputKey.Get().targetClientAddress == cls->sata.targetClientAddress;
36 }
37 
UDPProxyCoordinator()38 UDPProxyCoordinator::UDPProxyCoordinator()
39 {
40 
41 }
~UDPProxyCoordinator()42 UDPProxyCoordinator::~UDPProxyCoordinator()
43 {
44 	Clear();
45 }
SetRemoteLoginPassword(RakNet::RakString password)46 void UDPProxyCoordinator::SetRemoteLoginPassword(RakNet::RakString password)
47 {
48 	remoteLoginPassword=password;
49 }
Update(void)50 void UDPProxyCoordinator::Update(void)
51 {
52 	DataStructures::DefaultIndexType idx;
53 	RakNetTime curTime = RakNet::GetTime();
54 	ForwardingRequest *fw;
55 	idx=0;
56 	while (idx < forwardingRequestList.GetSize())
57 	{
58 		fw=forwardingRequestList[idx];
59 		if (fw->timeRequestedPings!=0 &&
60 			curTime > fw->timeRequestedPings + DEFAULT_UNRESPONSIVE_PING_TIME)
61 		{
62 			fw->OrderRemainingServersToTry();
63 			fw->timeRequestedPings=0;
64 			TryNextServer(fw->sata, fw);
65 			idx++;
66 		}
67 		else if (fw->timeoutAfterSuccess!=0 &&
68 			curTime > fw->timeoutAfterSuccess)
69 		{
70 			// Forwarding request succeeded, we waited a bit to prevent duplicates. Can forget about the entry now.
71 			RakNet::OP_DELETE(fw,__FILE__,__LINE__);
72 			forwardingRequestList.RemoveAtIndex(idx,__FILE__,__LINE__);
73 		}
74 		else
75 			idx++;
76 	}
77 }
OnReceive(Packet * packet)78 PluginReceiveResult UDPProxyCoordinator::OnReceive(Packet *packet)
79 {
80 	if (packet->data[0]==ID_UDP_PROXY_GENERAL && packet->length>1)
81 	{
82 		switch (packet->data[1])
83 		{
84 		case ID_UDP_PROXY_FORWARDING_REQUEST_FROM_CLIENT_TO_COORDINATOR:
85 			OnForwardingRequestFromClientToCoordinator(packet);
86 			return RR_STOP_PROCESSING_AND_DEALLOCATE;
87 		case ID_UDP_PROXY_LOGIN_REQUEST_FROM_SERVER_TO_COORDINATOR:
88 			OnLoginRequestFromServerToCoordinator(packet);
89 			return RR_STOP_PROCESSING_AND_DEALLOCATE;
90 		case ID_UDP_PROXY_FORWARDING_REPLY_FROM_SERVER_TO_COORDINATOR:
91 			OnForwardingReplyFromServerToCoordinator(packet);
92 			return RR_STOP_PROCESSING_AND_DEALLOCATE;
93 		case ID_UDP_PROXY_PING_SERVERS_REPLY_FROM_CLIENT_TO_COORDINATOR:
94 			OnPingServersReplyFromClientToCoordinator(packet);
95 			return RR_STOP_PROCESSING_AND_DEALLOCATE;
96 		}
97 	}
98 	return RR_CONTINUE_PROCESSING;
99 }
OnClosedConnection(SystemAddress systemAddress,RakNetGUID rakNetGUID,PI2_LostConnectionReason lostConnectionReason)100 void UDPProxyCoordinator::OnClosedConnection(SystemAddress systemAddress, RakNetGUID rakNetGUID, PI2_LostConnectionReason lostConnectionReason )
101 {
102 	(void) lostConnectionReason;
103 	(void) rakNetGUID;
104 
105 	DataStructures::DefaultIndexType idx, idx2;
106 
107 	idx=0;
108 	while (idx < forwardingRequestList.GetSize())
109 	{
110 		if (forwardingRequestList[idx]->requestingAddress==systemAddress)
111 		{
112 			// Guy disconnected before the attempt completed
113 			RakNet::OP_DELETE(forwardingRequestList[idx], __FILE__, __LINE__);
114 			forwardingRequestList.RemoveAtIndex(idx, __FILE__, __LINE__ );
115 		}
116 		else
117 			idx++;
118 	}
119 
120 	idx = serverList.GetIndexOf(systemAddress);
121 	if (idx!=(DataStructures::DefaultIndexType)-1)
122 	{
123 		ForwardingRequest *fw;
124 		// For each pending client for this server, choose from remaining servers.
125 		for (idx2=0; idx2 < forwardingRequestList.GetSize(); idx2++)
126 		{
127 			fw = forwardingRequestList[idx2];
128 			if (fw->currentlyAttemptedServerAddress==systemAddress)
129 			{
130 				// Try the next server
131 				TryNextServer(fw->sata, fw);
132 			}
133 		}
134 
135 		// Remove dead server
136 		serverList.RemoveAtIndex(idx, __FILE__, __LINE__ );
137 	}
138 }
OnForwardingRequestFromClientToCoordinator(Packet * packet)139 void UDPProxyCoordinator::OnForwardingRequestFromClientToCoordinator(Packet *packet)
140 {
141 	RakNet::BitStream incomingBs(packet->data, packet->length, false);
142 	incomingBs.IgnoreBytes(2);
143 	SystemAddress sourceAddress;
144 	incomingBs.Read(sourceAddress);
145 	if (sourceAddress==UNASSIGNED_SYSTEM_ADDRESS)
146 		sourceAddress=packet->systemAddress;
147 	SystemAddress targetAddress;
148 	RakNetGUID targetGuid;
149 	bool usesAddress;
150 	incomingBs.Read(usesAddress);
151 	if (usesAddress)
152 	{
153 		incomingBs.Read(targetAddress);
154 	}
155 	else
156 	{
157 		incomingBs.Read(targetGuid);
158 		targetAddress=rakPeerInterface->GetSystemAddressFromGuid(targetGuid);
159 	}
160 	ForwardingRequest *fw = RakNet::OP_NEW<ForwardingRequest>(__FILE__,__LINE__);
161 	fw->timeoutAfterSuccess=0;
162 	incomingBs.Read(fw->timeoutOnNoDataMS);
163 	bool hasServerSelectionBitstream;
164 	incomingBs.Read(hasServerSelectionBitstream);
165 	if (hasServerSelectionBitstream)
166 		incomingBs.Read(&(fw->serverSelectionBitstream));
167 
168 	RakNet::BitStream outgoingBs;
169 	SenderAndTargetAddress sata;
170 	sata.senderClientAddress=sourceAddress;
171 	sata.targetClientAddress=targetAddress;
172 	SenderAndTargetAddress sataReversed;
173 	sataReversed.senderClientAddress=targetAddress;
174 	sataReversed.targetClientAddress=sourceAddress;
175 	DataStructures::DefaultIndexType insertionIndex;
176 	insertionIndex = forwardingRequestList.GetInsertionIndex(sata);
177 	if (insertionIndex==(DataStructures::DefaultIndexType)-1 ||
178 		forwardingRequestList.GetInsertionIndex(sataReversed)==(DataStructures::DefaultIndexType)-1)
179 	{
180 		outgoingBs.Write((MessageID)ID_UDP_PROXY_GENERAL);
181 		outgoingBs.Write((MessageID)ID_UDP_PROXY_IN_PROGRESS);
182 		outgoingBs.Write(sata.senderClientAddress);
183 		outgoingBs.Write(targetAddress);
184 		rakPeerInterface->Send(&outgoingBs, MEDIUM_PRIORITY, RELIABLE_ORDERED, 0, packet->systemAddress, false);
185 		RakNet::OP_DELETE(fw, __FILE__, __LINE__);
186 		return;
187 	}
188 
189 	if (serverList.GetSize()==0)
190 	{
191 		outgoingBs.Write((MessageID)ID_UDP_PROXY_GENERAL);
192 		outgoingBs.Write((MessageID)ID_UDP_PROXY_NO_SERVERS_ONLINE);
193 		outgoingBs.Write(sata.senderClientAddress);
194 		outgoingBs.Write(targetAddress);
195 		rakPeerInterface->Send(&outgoingBs, MEDIUM_PRIORITY, RELIABLE_ORDERED, 0, packet->systemAddress, false);
196 		RakNet::OP_DELETE(fw, __FILE__, __LINE__);
197 		return;
198 	}
199 
200 	if (rakPeerInterface->IsConnected(targetAddress)==false && usesAddress==false)
201 	{
202 		outgoingBs.Write((MessageID)ID_UDP_PROXY_GENERAL);
203 		outgoingBs.Write((MessageID)ID_UDP_PROXY_RECIPIENT_GUID_NOT_CONNECTED_TO_COORDINATOR);
204 		outgoingBs.Write(sata.senderClientAddress);
205 		outgoingBs.Write(targetAddress);
206 		outgoingBs.Write(targetGuid);
207 		rakPeerInterface->Send(&outgoingBs, MEDIUM_PRIORITY, RELIABLE_ORDERED, 0, packet->systemAddress, false);
208 		RakNet::OP_DELETE(fw, __FILE__, __LINE__);
209 		return;
210 	}
211 
212 	fw->sata=sata;
213 	fw->requestingAddress=packet->systemAddress;
214 
215 	if (serverList.GetSize()>1)
216 	{
217 		outgoingBs.Write((MessageID)ID_UDP_PROXY_GENERAL);
218 		outgoingBs.Write((MessageID)ID_UDP_PROXY_PING_SERVERS_FROM_COORDINATOR_TO_CLIENT);
219 		outgoingBs.Write(sourceAddress);
220 		outgoingBs.Write(targetAddress);
221 		unsigned short serverListSize = (unsigned short) serverList.GetSize();
222 		outgoingBs.Write(serverListSize);
223 		DataStructures::DefaultIndexType idx;
224 		for (idx=0; idx < serverList.GetSize(); idx++)
225 			outgoingBs.Write(serverList[idx]);
226 		rakPeerInterface->Send(&outgoingBs, MEDIUM_PRIORITY, RELIABLE_ORDERED, 0, sourceAddress, false);
227 		rakPeerInterface->Send(&outgoingBs, MEDIUM_PRIORITY, RELIABLE_ORDERED, 0, targetAddress, false);
228 		fw->timeRequestedPings=RakNet::GetTime();
229 		DataStructures::DefaultIndexType copyIndex;
230 		for (copyIndex=0; copyIndex < serverList.GetSize(); copyIndex++)
231 			fw->remainingServersToTry.Push(serverList[copyIndex], __FILE__, __LINE__ );
232 		forwardingRequestList.InsertAtIndex(fw, insertionIndex, __FILE__, __LINE__ );
233 	}
234 	else
235 	{
236 		fw->timeRequestedPings=0;
237 		fw->currentlyAttemptedServerAddress=serverList[0];
238 		forwardingRequestList.InsertAtIndex(fw, insertionIndex, __FILE__, __LINE__ );
239 		SendForwardingRequest(sourceAddress, targetAddress, fw->currentlyAttemptedServerAddress, fw->timeoutOnNoDataMS);
240 	}
241 }
242 
SendForwardingRequest(SystemAddress sourceAddress,SystemAddress targetAddress,SystemAddress serverAddress,RakNetTimeMS timeoutOnNoDataMS)243 void UDPProxyCoordinator::SendForwardingRequest(SystemAddress sourceAddress, SystemAddress targetAddress, SystemAddress serverAddress, RakNetTimeMS timeoutOnNoDataMS)
244 {
245 	RakNet::BitStream outgoingBs;
246 	// Send request to desired server
247 	outgoingBs.Write((MessageID)ID_UDP_PROXY_GENERAL);
248 	outgoingBs.Write((MessageID)ID_UDP_PROXY_FORWARDING_REQUEST_FROM_COORDINATOR_TO_SERVER);
249 	outgoingBs.Write(sourceAddress);
250 	outgoingBs.Write(targetAddress);
251 	outgoingBs.Write(timeoutOnNoDataMS);
252 	rakPeerInterface->Send(&outgoingBs, MEDIUM_PRIORITY, RELIABLE_ORDERED, 0, serverAddress, false);
253 }
OnLoginRequestFromServerToCoordinator(Packet * packet)254 void UDPProxyCoordinator::OnLoginRequestFromServerToCoordinator(Packet *packet)
255 {
256 	RakNet::BitStream incomingBs(packet->data, packet->length, false);
257 	incomingBs.IgnoreBytes(2);
258 	RakNet::RakString password;
259 	incomingBs.Read(password);
260 	RakNet::BitStream outgoingBs;
261 
262 	if (remoteLoginPassword.IsEmpty())
263 	{
264 		outgoingBs.Write((MessageID)ID_UDP_PROXY_GENERAL);
265 		outgoingBs.Write((MessageID)ID_UDP_PROXY_NO_PASSWORD_SET_FROM_COORDINATOR_TO_SERVER);
266 		outgoingBs.Write(password);
267 		rakPeerInterface->Send(&outgoingBs, MEDIUM_PRIORITY, RELIABLE_ORDERED, 0, packet->systemAddress, false);
268 		return;
269 	}
270 
271 	if (remoteLoginPassword!=password)
272 	{
273 		outgoingBs.Write((MessageID)ID_UDP_PROXY_GENERAL);
274 		outgoingBs.Write((MessageID)ID_UDP_PROXY_WRONG_PASSWORD_FROM_COORDINATOR_TO_SERVER);
275 		outgoingBs.Write(password);
276 		rakPeerInterface->Send(&outgoingBs, MEDIUM_PRIORITY, RELIABLE_ORDERED, 0, packet->systemAddress, false);
277 		return;
278 	}
279 
280 	DataStructures::DefaultIndexType insertionIndex;
281 	insertionIndex=serverList.GetInsertionIndex(packet->systemAddress);
282 	if (insertionIndex==(DataStructures::DefaultIndexType)-1)
283 	{
284 		outgoingBs.Write((MessageID)ID_UDP_PROXY_GENERAL);
285 		outgoingBs.Write((MessageID)ID_UDP_PROXY_ALREADY_LOGGED_IN_FROM_COORDINATOR_TO_SERVER);
286 		outgoingBs.Write(password);
287 		rakPeerInterface->Send(&outgoingBs, MEDIUM_PRIORITY, RELIABLE_ORDERED, 0, packet->systemAddress, false);
288 		return;
289 	}
290 	serverList.InsertAtIndex(packet->systemAddress, insertionIndex, __FILE__, __LINE__ );
291 	outgoingBs.Write((MessageID)ID_UDP_PROXY_GENERAL);
292 	outgoingBs.Write((MessageID)ID_UDP_PROXY_LOGIN_SUCCESS_FROM_COORDINATOR_TO_SERVER);
293 	outgoingBs.Write(password);
294 	rakPeerInterface->Send(&outgoingBs, MEDIUM_PRIORITY, RELIABLE_ORDERED, 0, packet->systemAddress, false);
295 }
OnForwardingReplyFromServerToCoordinator(Packet * packet)296 void UDPProxyCoordinator::OnForwardingReplyFromServerToCoordinator(Packet *packet)
297 {
298 	RakNet::BitStream incomingBs(packet->data, packet->length, false);
299 	incomingBs.IgnoreBytes(2);
300 	SenderAndTargetAddress sata;
301 	incomingBs.Read(sata.senderClientAddress);
302 	incomingBs.Read(sata.targetClientAddress);
303 	DataStructures::DefaultIndexType index = forwardingRequestList.GetIndexOf(sata);
304 	if (index==(DataStructures::DefaultIndexType)-1)
305 	{
306 		// The guy disconnected before the request finished
307 		return;
308 	}
309 	ForwardingRequest *fw = forwardingRequestList[index];
310 
311 	UDPForwarderResult success;
312 	unsigned char c;
313 	incomingBs.Read(c);
314 	success=(UDPForwarderResult)c;
315 
316 	RakNet::BitStream outgoingBs;
317 	if (success==UDPFORWARDER_SUCCESS)
318 	{
319 		char serverIP[64];
320 		packet->systemAddress.ToString(false,serverIP);
321 		unsigned short forwardingPort;
322 		incomingBs.Read(forwardingPort);
323 
324 		outgoingBs.Write((MessageID)ID_UDP_PROXY_GENERAL);
325 		outgoingBs.Write((MessageID)ID_UDP_PROXY_FORWARDING_SUCCEEDED);
326 		outgoingBs.Write(sata.senderClientAddress);
327 		outgoingBs.Write(sata.targetClientAddress);
328 		outgoingBs.Write(RakNet::RakString(serverIP));
329 		outgoingBs.Write(forwardingPort);
330 		rakPeerInterface->Send(&outgoingBs, MEDIUM_PRIORITY, RELIABLE_ORDERED, 0, fw->requestingAddress, false);
331 
332 		outgoingBs.Reset();
333 		outgoingBs.Write((MessageID)ID_UDP_PROXY_GENERAL);
334 		outgoingBs.Write((MessageID)ID_UDP_PROXY_FORWARDING_NOTIFICATION);
335 		outgoingBs.Write(sata.senderClientAddress);
336 		outgoingBs.Write(sata.targetClientAddress);
337 		outgoingBs.Write(RakNet::RakString(serverIP));
338 		outgoingBs.Write(forwardingPort);
339 		rakPeerInterface->Send(&outgoingBs, MEDIUM_PRIORITY, RELIABLE_ORDERED, 0, sata.targetClientAddress, false);
340 
341 		// 05/18/09 Keep the entry around for some time after success, so duplicates are reported if attempting forwarding from the target system before notification of success
342 		fw->timeoutAfterSuccess=RakNet::GetTime()+fw->timeoutOnNoDataMS;
343 		// forwardingRequestList.RemoveAtIndex(index);
344 		// RakNet::OP_DELETE(fw,__FILE__,__LINE__);
345 
346 		return;
347 	}
348 	else if (success==UDPFORWARDER_NO_SOCKETS)
349 	{
350 		// Try next server
351 		TryNextServer(sata, fw);
352 	}
353 	else
354 	{
355 		RakAssert(success==UDPFORWARDER_FORWARDING_ALREADY_EXISTS);
356 
357 		// Return in progress
358 		outgoingBs.Write((MessageID)ID_UDP_PROXY_GENERAL);
359 		outgoingBs.Write((MessageID)ID_UDP_PROXY_IN_PROGRESS);
360 		outgoingBs.Write(sata.senderClientAddress);
361 		outgoingBs.Write(sata.targetClientAddress);
362 		rakPeerInterface->Send(&outgoingBs, MEDIUM_PRIORITY, RELIABLE_ORDERED, 0, fw->requestingAddress, false);
363 		forwardingRequestList.RemoveAtIndex(index,__FILE__,__LINE__);
364 		RakNet::OP_DELETE(fw,__FILE__,__LINE__);
365 	}
366 }
OnPingServersReplyFromClientToCoordinator(Packet * packet)367 void UDPProxyCoordinator::OnPingServersReplyFromClientToCoordinator(Packet *packet)
368 {
369 	RakNet::BitStream incomingBs(packet->data, packet->length, false);
370 	incomingBs.IgnoreBytes(2);
371 	unsigned short serversToPingSize;
372 	SystemAddress serverAddress;
373 	SenderAndTargetAddress sata;
374 	incomingBs.Read(sata.senderClientAddress);
375 	incomingBs.Read(sata.targetClientAddress);
376 	DataStructures::DefaultIndexType index = forwardingRequestList.GetIndexOf(sata);
377 	if (index==(DataStructures::DefaultIndexType)-1)
378 		return;
379 	unsigned short idx;
380 	ServerWithPing swp;
381 	ForwardingRequest *fw = forwardingRequestList[index];
382 	if (fw->timeRequestedPings==0)
383 		return;
384 
385 	incomingBs.Read(serversToPingSize);
386 	if (packet->systemAddress==sata.senderClientAddress)
387 	{
388 		for (idx=0; idx < serversToPingSize; idx++)
389 		{
390 			incomingBs.Read(swp.serverAddress);
391 			incomingBs.Read(swp.ping);
392 			fw->sourceServerPings.Push(swp, swp.ping, __FILE__, __LINE__);
393 		}
394 	}
395 	else
396 	{
397 		for (idx=0; idx < serversToPingSize; idx++)
398 		{
399 			incomingBs.Read(swp.serverAddress);
400 			incomingBs.Read(swp.ping);
401 			fw->targetServerPings.Push(swp, swp.ping, __FILE__, __LINE__);
402 		}
403 	}
404 
405 	// Both systems have to give us pings to progress here. Otherwise will timeout in Update()
406 	if (fw->sourceServerPings.GetSize()>0 &&
407 		fw->targetServerPings.GetSize()>0)
408 	{
409 		fw->OrderRemainingServersToTry();
410 		fw->timeRequestedPings=0;
411 		TryNextServer(fw->sata, fw);
412 	}
413 }
TryNextServer(SenderAndTargetAddress sata,ForwardingRequest * fw)414 void UDPProxyCoordinator::TryNextServer(SenderAndTargetAddress sata, ForwardingRequest *fw)
415 {
416 	bool pickedGoodServer=false;
417 	while(fw->remainingServersToTry.GetSize()>0)
418 	{
419 		fw->currentlyAttemptedServerAddress=fw->remainingServersToTry.Pop(__FILE__, __LINE__ );
420 		if (serverList.GetIndexOf(fw->currentlyAttemptedServerAddress)!=(DataStructures::DefaultIndexType)-1)
421 		{
422 			pickedGoodServer=true;
423 			break;
424 		}
425 	}
426 
427 	if (pickedGoodServer==false)
428 	{
429 		SendAllBusy(sata.senderClientAddress, sata.targetClientAddress, fw->requestingAddress);
430 		forwardingRequestList.RemoveAtKey(sata,true,__FILE__,__LINE__);
431 		RakNet::OP_DELETE(fw,__FILE__,__LINE__);
432 		return;
433 	}
434 
435 	SendForwardingRequest(sata.senderClientAddress, sata.targetClientAddress, fw->currentlyAttemptedServerAddress, fw->timeoutOnNoDataMS);
436 }
SendAllBusy(SystemAddress senderClientAddress,SystemAddress targetClientAddress,SystemAddress requestingAddress)437 void UDPProxyCoordinator::SendAllBusy(SystemAddress senderClientAddress, SystemAddress targetClientAddress, SystemAddress requestingAddress)
438 {
439 	RakNet::BitStream outgoingBs;
440 	outgoingBs.Write((MessageID)ID_UDP_PROXY_GENERAL);
441 	outgoingBs.Write((MessageID)ID_UDP_PROXY_ALL_SERVERS_BUSY);
442 	outgoingBs.Write(senderClientAddress);
443 	outgoingBs.Write(targetClientAddress);
444 	rakPeerInterface->Send(&outgoingBs, MEDIUM_PRIORITY, RELIABLE_ORDERED, 0, requestingAddress, false);
445 }
Clear(void)446 void UDPProxyCoordinator::Clear(void)
447 {
448 	serverList.Clear(true, __FILE__, __LINE__);
449 	forwardingRequestList.ClearPointers(true, __FILE__, __LINE__);
450 }
OrderRemainingServersToTry(void)451 void UDPProxyCoordinator::ForwardingRequest::OrderRemainingServersToTry(void)
452 {
453 	DataStructures::Multilist<ML_ORDERED_LIST,UDPProxyCoordinator::ServerWithPing,unsigned short> swpList;
454 	swpList.SetSortOrder(true);
455 	if (sourceServerPings.GetSize()==0 && targetServerPings.GetSize()==0)
456 		return;
457 
458 	DataStructures::DefaultIndexType idx;
459 	UDPProxyCoordinator::ServerWithPing swp;
460 	for (idx=0; idx < remainingServersToTry.GetSize(); idx++)
461 	{
462 		swp.serverAddress=remainingServersToTry[idx];
463 		swp.ping=0;
464 		if (sourceServerPings.GetSize())
465 			swp.ping+=(unsigned short) sourceServerPings[idx].ping;
466 		else
467 			swp.ping+=(unsigned short) DEFAULT_CLIENT_UNRESPONSIVE_PING_TIME;
468 		if (targetServerPings.GetSize())
469 			swp.ping+=(unsigned short) targetServerPings[idx].ping;
470 		else
471 			swp.ping+=(unsigned short) DEFAULT_CLIENT_UNRESPONSIVE_PING_TIME;
472 		swpList.Push(swp, swp.ping, __FILE__, __LINE__);
473 	}
474 	remainingServersToTry.Clear(true, __FILE__, __LINE__ );
475 	for (idx=0; idx < swpList.GetSize(); idx++)
476 	{
477 		remainingServersToTry.Push(swpList[idx].serverAddress, __FILE__, __LINE__ );
478 	}
479 }
480 
481 #endif // _RAKNET_SUPPORT_*
482