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