SLikeNet 0.1.3

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
UDPProxyCoordinator.cpp
Go to the documentation of this file.
1 /*
2 * Original work: Copyright (c) 2014, Oculus VR, Inc.
3 * All rights reserved.
4 *
5 * This source code is licensed under the BSD-style license found in the
6 * RakNet License.txt file in the licenses directory of this source tree. An additional grant
7 * of patent rights can be found in the RakNet Patents.txt file in the same directory.
8 *
9 *
10 * Modified work: Copyright (c) 2016-2018, SLikeSoft UG (haftungsbeschränkt)
11 *
12 * This source code was modified by SLikeSoft. Modifications are licensed under the MIT-style
13 * license found in the license.txt file in the root directory of this source tree.
14 */
15
16 #include "slikenet/NativeFeatureIncludes.h"
17 #if _RAKNET_SUPPORT_UDPProxyCoordinator==1 && _RAKNET_SUPPORT_UDPForwarder==1
18
19 #include "slikenet/UDPProxyCoordinator.h"
20 #include "slikenet/BitStream.h"
21 #include "slikenet/UDPProxyCommon.h"
22 #include "slikenet/peerinterface.h"
23 #include "slikenet/MessageIdentifiers.h"
24 #include "slikenet/Rand.h"
25 #include "slikenet/GetTime.h"
26 #include "slikenet/UDPForwarder.h"
27
28 // Larger than the client version
29 static const int DEFAULT_CLIENT_UNRESPONSIVE_PING_TIME=2000;
30 static const int DEFAULT_UNRESPONSIVE_PING_TIME_COORDINATOR=DEFAULT_CLIENT_UNRESPONSIVE_PING_TIME+1000;
31
32 using namespace SLNet;
33
34 // bool operator<( const DataStructures::MLKeyRef<unsigned short> &inputKey, const UDPProxyCoordinator::ServerWithPing &cls ) {return inputKey.Get() < cls.ping;}
35 // bool operator>( const DataStructures::MLKeyRef<unsigned short> &inputKey, const UDPProxyCoordinator::ServerWithPing &cls ) {return inputKey.Get() > cls.ping;}
36 // bool operator==( const DataStructures::MLKeyRef<unsigned short> &inputKey, const UDPProxyCoordinator::ServerWithPing &cls ) {return inputKey.Get() == cls.ping;}
37
38 int UDPProxyCoordinator::ServerWithPingComp( const unsigned short &key, const UDPProxyCoordinator::ServerWithPing &data )
39 {
40 if (key < data.ping)
41 return -1;
42 if (key > data.ping)
43 return 1;
44 return 0;
45 }
46
47 int UDPProxyCoordinator::ForwardingRequestComp( const SenderAndTargetAddress &key, ForwardingRequest* const &data)
48 {
49 if (key.senderClientAddress < data->sata.senderClientAddress )
50 return -1;
51 if (key.senderClientAddress > data->sata.senderClientAddress )
52 return 1;
53 if (key.targetClientAddress < data->sata.targetClientAddress )
54 return -1;
55 if (key.targetClientAddress > data->sata.targetClientAddress )
56 return 1;
57 return 0;
58 }
59 //
60 // bool operator<( const DataStructures::MLKeyRef<UDPProxyCoordinator::SenderAndTargetAddress> &inputKey, const UDPProxyCoordinator::ForwardingRequest *cls )
61 // {
62 // return inputKey.Get().senderClientAddress < cls->sata.senderClientAddress ||
63 // (inputKey.Get().senderClientAddress == cls->sata.senderClientAddress && inputKey.Get().targetClientAddress < cls->sata.targetClientAddress);
64 // }
65 // bool operator>( const DataStructures::MLKeyRef<UDPProxyCoordinator::SenderAndTargetAddress> &inputKey, const UDPProxyCoordinator::ForwardingRequest *cls )
66 // {
67 // return inputKey.Get().senderClientAddress > cls->sata.senderClientAddress ||
68 // (inputKey.Get().senderClientAddress == cls->sata.senderClientAddress && inputKey.Get().targetClientAddress > cls->sata.targetClientAddress);
69 // }
70 // bool operator==( const DataStructures::MLKeyRef<UDPProxyCoordinator::SenderAndTargetAddress> &inputKey, const UDPProxyCoordinator::ForwardingRequest *cls )
71 // {
72 // return inputKey.Get().senderClientAddress == cls->sata.senderClientAddress && inputKey.Get().targetClientAddress == cls->sata.targetClientAddress;
73 // }
74
75 STATIC_FACTORY_DEFINITIONS(UDPProxyCoordinator,UDPProxyCoordinator);
76
77 UDPProxyCoordinator::UDPProxyCoordinator()
78 {
79
80 }
81 UDPProxyCoordinator::~UDPProxyCoordinator()
82 {
83 Clear();
84 }
85 void UDPProxyCoordinator::SetRemoteLoginPassword(SLNet::RakString password)
86 {
87 remoteLoginPassword=password;
88 }
89 void UDPProxyCoordinator::Update(void)
90 {
91 unsigned int idx;
92 SLNet::TimeMS curTime = SLNet::GetTimeMS();
93 ForwardingRequest *fw;
94 idx=0;
95 while (idx < forwardingRequestList.Size())
96 {
97 fw=forwardingRequestList[idx];
98 if (fw->timeRequestedPings!=0 &&
99 curTime > fw->timeRequestedPings + DEFAULT_UNRESPONSIVE_PING_TIME_COORDINATOR)
100 {
101 fw->OrderRemainingServersToTry();
102 fw->timeRequestedPings=0;
103 TryNextServer(fw->sata, fw);
104 idx++;
105 }
106 else if (fw->timeoutAfterSuccess!=0 &&
107 curTime > fw->timeoutAfterSuccess)
108 {
109 // Forwarding request succeeded, we waited a bit to prevent duplicates. Can forget about the entry now.
110 SLNet::OP_DELETE(fw,_FILE_AND_LINE_);
111 forwardingRequestList.RemoveAtIndex(idx);
112 }
113 else
114 idx++;
115 }
116 }
117 PluginReceiveResult UDPProxyCoordinator::OnReceive(Packet *packet)
118 {
119 if (packet->data[0]==ID_UDP_PROXY_GENERAL && packet->length>1)
120 {
121 switch (packet->data[1])
122 {
123 case ID_UDP_PROXY_FORWARDING_REQUEST_FROM_CLIENT_TO_COORDINATOR:
124 OnForwardingRequestFromClientToCoordinator(packet);
125 return RR_STOP_PROCESSING_AND_DEALLOCATE;
126 case ID_UDP_PROXY_LOGIN_REQUEST_FROM_SERVER_TO_COORDINATOR:
127 OnLoginRequestFromServerToCoordinator(packet);
128 return RR_STOP_PROCESSING_AND_DEALLOCATE;
129 case ID_UDP_PROXY_FORWARDING_REPLY_FROM_SERVER_TO_COORDINATOR:
130 OnForwardingReplyFromServerToCoordinator(packet);
131 return RR_STOP_PROCESSING_AND_DEALLOCATE;
132 case ID_UDP_PROXY_PING_SERVERS_REPLY_FROM_CLIENT_TO_COORDINATOR:
133 OnPingServersReplyFromClientToCoordinator(packet);
134 return RR_STOP_PROCESSING_AND_DEALLOCATE;
135 }
136 }
137 return RR_CONTINUE_PROCESSING;
138 }
139 void UDPProxyCoordinator::OnClosedConnection(const SystemAddress &systemAddress, RakNetGUID rakNetGUID, PI2_LostConnectionReason lostConnectionReason )
140 {
141 (void) lostConnectionReason;
142 (void) rakNetGUID;
143
144 unsigned int idx, idx2;
145
146 idx=0;
147 while (idx < forwardingRequestList.Size())
148 {
149 if (forwardingRequestList[idx]->requestingAddress==systemAddress)
150 {
151 // Guy disconnected before the attempt completed
152 SLNet::OP_DELETE(forwardingRequestList[idx], _FILE_AND_LINE_);
153 forwardingRequestList.RemoveAtIndex(idx );
154 }
155 else
156 idx++;
157 }
158
159 idx = serverList.GetIndexOf(systemAddress);
160 if (idx!=(unsigned int)-1)
161 {
162 ForwardingRequest *fw;
163 // For each pending client for this server, choose from remaining servers.
164 for (idx2=0; idx2 < forwardingRequestList.Size(); idx2++)
165 {
166 fw = forwardingRequestList[idx2];
167 if (fw->currentlyAttemptedServerAddress==systemAddress)
168 {
169 // Try the next server
170 TryNextServer(fw->sata, fw);
171 }
172 }
173
174 // Remove dead server
175 serverList.RemoveAtIndexFast(idx);
176 }
177 }
178 void UDPProxyCoordinator::OnForwardingRequestFromClientToCoordinator(Packet *packet)
179 {
180 SLNet::BitStream incomingBs(packet->data, packet->length, false);
181 incomingBs.IgnoreBytes(2);
182 SystemAddress sourceAddress;
183 incomingBs.Read(sourceAddress);
184 if (sourceAddress==UNASSIGNED_SYSTEM_ADDRESS)
185 sourceAddress=packet->systemAddress;
186 SystemAddress targetAddress;
187 RakNetGUID targetGuid;
188 bool usesAddress=false;
189 incomingBs.Read(usesAddress);
190 if (usesAddress)
191 {
192 incomingBs.Read(targetAddress);
193 targetGuid=rakPeerInterface->GetGuidFromSystemAddress(targetAddress);
194 }
195 else
196 {
197 incomingBs.Read(targetGuid);
198 targetAddress=rakPeerInterface->GetSystemAddressFromGuid(targetGuid);
199 }
200 ForwardingRequest *fw = SLNet::OP_NEW<ForwardingRequest>(_FILE_AND_LINE_);
201 fw->timeoutAfterSuccess=0;
202 incomingBs.Read(fw->timeoutOnNoDataMS);
203 bool hasServerSelectionBitstream=false;
204 incomingBs.Read(hasServerSelectionBitstream);
205 if (hasServerSelectionBitstream)
206 incomingBs.Read(&(fw->serverSelectionBitstream));
207
208 SLNet::BitStream outgoingBs;
209 SenderAndTargetAddress sata;
210 sata.senderClientAddress=sourceAddress;
211 sata.targetClientAddress=targetAddress;
212 sata.targetClientGuid=targetGuid;
213 sata.senderClientGuid=rakPeerInterface->GetGuidFromSystemAddress(sourceAddress);
214 SenderAndTargetAddress sataReversed;
215 sataReversed.senderClientAddress=targetAddress;
216 sataReversed.targetClientAddress=sourceAddress;
217 sataReversed.senderClientGuid=sata.targetClientGuid;
218 sataReversed.targetClientGuid=sata.senderClientGuid;
219
220 unsigned int insertionIndex;
221 bool objectExists1, objectExists2;
222 insertionIndex=forwardingRequestList.GetIndexFromKey(sata, &objectExists1);
223 forwardingRequestList.GetIndexFromKey(sataReversed, &objectExists2);
224
225 if (objectExists1 || objectExists2)
226 {
227 outgoingBs.Write((MessageID)ID_UDP_PROXY_GENERAL);
228 outgoingBs.Write((MessageID)ID_UDP_PROXY_IN_PROGRESS);
229 outgoingBs.Write(sata.senderClientAddress);
230 outgoingBs.Write(targetAddress);
231 outgoingBs.Write(targetGuid);
232 // Request in progress, not completed
233 unsigned short forwardingPort=0;
234 RakString serverPublicIp;
235 outgoingBs.Write(serverPublicIp);
236 outgoingBs.Write(forwardingPort);
237 rakPeerInterface->Send(&outgoingBs, MEDIUM_PRIORITY, RELIABLE_ORDERED, 0, packet->systemAddress, false);
238 SLNet::OP_DELETE(fw, _FILE_AND_LINE_);
239 return;
240 }
241
242 if (serverList.Size()==0)
243 {
244 outgoingBs.Write((MessageID)ID_UDP_PROXY_GENERAL);
245 outgoingBs.Write((MessageID)ID_UDP_PROXY_NO_SERVERS_ONLINE);
246 outgoingBs.Write(sata.senderClientAddress);
247 outgoingBs.Write(targetAddress);
248 outgoingBs.Write(targetGuid);
249 rakPeerInterface->Send(&outgoingBs, MEDIUM_PRIORITY, RELIABLE_ORDERED, 0, packet->systemAddress, false);
250 SLNet::OP_DELETE(fw, _FILE_AND_LINE_);
251 return;
252 }
253
254 if (rakPeerInterface->GetConnectionState(targetAddress)!=IS_CONNECTED && usesAddress==false)
255 {
256 outgoingBs.Write((MessageID)ID_UDP_PROXY_GENERAL);
257 outgoingBs.Write((MessageID)ID_UDP_PROXY_RECIPIENT_GUID_NOT_CONNECTED_TO_COORDINATOR);
258 outgoingBs.Write(sata.senderClientAddress);
259 outgoingBs.Write(targetAddress);
260 outgoingBs.Write(targetGuid);
261 rakPeerInterface->Send(&outgoingBs, MEDIUM_PRIORITY, RELIABLE_ORDERED, 0, packet->systemAddress, false);
262 SLNet::OP_DELETE(fw, _FILE_AND_LINE_);
263 return;
264 }
265
266 fw->sata=sata;
267 fw->requestingAddress=packet->systemAddress;
268
269 if (serverList.Size()>1)
270 {
271 outgoingBs.Write((MessageID)ID_UDP_PROXY_GENERAL);
272 outgoingBs.Write((MessageID)ID_UDP_PROXY_PING_SERVERS_FROM_COORDINATOR_TO_CLIENT);
273 outgoingBs.Write(sourceAddress);
274 outgoingBs.Write(targetAddress);
275 outgoingBs.Write(targetGuid);
276 unsigned short serverListSize = (unsigned short) serverList.Size();
277 outgoingBs.Write(serverListSize);
278 unsigned int idx;
279 for (idx=0; idx < serverList.Size(); idx++)
280 outgoingBs.Write(serverList[idx]);
281 rakPeerInterface->Send(&outgoingBs, MEDIUM_PRIORITY, RELIABLE_ORDERED, 0, sourceAddress, false);
282 rakPeerInterface->Send(&outgoingBs, MEDIUM_PRIORITY, RELIABLE_ORDERED, 0, targetAddress, false);
283 fw->timeRequestedPings= SLNet::GetTimeMS();
284 unsigned int copyIndex;
285 for (copyIndex=0; copyIndex < serverList.Size(); copyIndex++)
286 fw->remainingServersToTry.Push(serverList[copyIndex], _FILE_AND_LINE_ );
287 forwardingRequestList.InsertAtIndex(fw, insertionIndex, _FILE_AND_LINE_ );
288 }
289 else
290 {
291 fw->timeRequestedPings=0;
292 fw->currentlyAttemptedServerAddress=serverList[0];
293 forwardingRequestList.InsertAtIndex(fw, insertionIndex, _FILE_AND_LINE_ );
294 SendForwardingRequest(sourceAddress, targetAddress, fw->currentlyAttemptedServerAddress, fw->timeoutOnNoDataMS);
295 }
296 }
297
298 void UDPProxyCoordinator::SendForwardingRequest(SystemAddress sourceAddress, SystemAddress targetAddress, SystemAddress serverAddress, SLNet::TimeMS timeoutOnNoDataMS)
299 {
300 SLNet::BitStream outgoingBs;
301 // Send request to desired server
302 outgoingBs.Write((MessageID)ID_UDP_PROXY_GENERAL);
303 outgoingBs.Write((MessageID)ID_UDP_PROXY_FORWARDING_REQUEST_FROM_COORDINATOR_TO_SERVER);
304 outgoingBs.Write(sourceAddress);
305 outgoingBs.Write(targetAddress);
306 outgoingBs.Write(timeoutOnNoDataMS);
307 rakPeerInterface->Send(&outgoingBs, MEDIUM_PRIORITY, RELIABLE_ORDERED, 0, serverAddress, false);
308 }
309 void UDPProxyCoordinator::OnLoginRequestFromServerToCoordinator(Packet *packet)
310 {
311 SLNet::BitStream incomingBs(packet->data, packet->length, false);
312 incomingBs.IgnoreBytes(2);
313 SLNet::RakString password;
314 incomingBs.Read(password);
315 SLNet::BitStream outgoingBs;
316
317 if (remoteLoginPassword.IsEmpty())
318 {
319 outgoingBs.Write((MessageID)ID_UDP_PROXY_GENERAL);
320 outgoingBs.Write((MessageID)ID_UDP_PROXY_NO_PASSWORD_SET_FROM_COORDINATOR_TO_SERVER);
321 outgoingBs.Write(password);
322 rakPeerInterface->Send(&outgoingBs, MEDIUM_PRIORITY, RELIABLE_ORDERED, 0, packet->systemAddress, false);
323 return;
324 }
325
326 if (remoteLoginPassword!=password)
327 {
328 outgoingBs.Write((MessageID)ID_UDP_PROXY_GENERAL);
329 outgoingBs.Write((MessageID)ID_UDP_PROXY_WRONG_PASSWORD_FROM_COORDINATOR_TO_SERVER);
330 outgoingBs.Write(password);
331 rakPeerInterface->Send(&outgoingBs, MEDIUM_PRIORITY, RELIABLE_ORDERED, 0, packet->systemAddress, false);
332 return;
333 }
334
335 unsigned int insertionIndex;
336 insertionIndex=serverList.GetIndexOf(packet->systemAddress);
337 if (insertionIndex!=(unsigned int)-1)
338 {
339 outgoingBs.Write((MessageID)ID_UDP_PROXY_GENERAL);
340 outgoingBs.Write((MessageID)ID_UDP_PROXY_ALREADY_LOGGED_IN_FROM_COORDINATOR_TO_SERVER);
341 outgoingBs.Write(password);
342 rakPeerInterface->Send(&outgoingBs, MEDIUM_PRIORITY, RELIABLE_ORDERED, 0, packet->systemAddress, false);
343 return;
344 }
345 serverList.Push(packet->systemAddress, _FILE_AND_LINE_ );
346 outgoingBs.Write((MessageID)ID_UDP_PROXY_GENERAL);
347 outgoingBs.Write((MessageID)ID_UDP_PROXY_LOGIN_SUCCESS_FROM_COORDINATOR_TO_SERVER);
348 outgoingBs.Write(password);
349 rakPeerInterface->Send(&outgoingBs, MEDIUM_PRIORITY, RELIABLE_ORDERED, 0, packet->systemAddress, false);
350 }
351 void UDPProxyCoordinator::OnForwardingReplyFromServerToCoordinator(Packet *packet)
352 {
353 SLNet::BitStream incomingBs(packet->data, packet->length, false);
354 incomingBs.IgnoreBytes(2);
355 SenderAndTargetAddress sata;
356 incomingBs.Read(sata.senderClientAddress);
357 incomingBs.Read(sata.targetClientAddress);
358 bool objectExists;
359 unsigned int index = forwardingRequestList.GetIndexFromKey(sata, &objectExists);
360 if (objectExists==false)
361 {
362 // The guy disconnected before the request finished
363 return;
364 }
365 ForwardingRequest *fw = forwardingRequestList[index];
366 sata.senderClientGuid = fw->sata.senderClientGuid;
367 sata.targetClientGuid = fw->sata.targetClientGuid;
368
369 RakString serverPublicIp;
370 incomingBs.Read(serverPublicIp);
371
372 if (serverPublicIp.IsEmpty())
373 {
374 char serverIP[64];
375 packet->systemAddress.ToString(false,serverIP,static_cast<size_t>(64));
376 serverPublicIp=serverIP;
377 }
378
379 UDPForwarderResult success;
380 unsigned char c;
381 incomingBs.Read(c);
382 success=(UDPForwarderResult)c;
383
384 unsigned short forwardingPort;
385 incomingBs.Read(forwardingPort);
386
387 SLNet::BitStream outgoingBs;
388 if (success==UDPFORWARDER_SUCCESS)
389 {
390 outgoingBs.Write((MessageID)ID_UDP_PROXY_GENERAL);
391 outgoingBs.Write((MessageID)ID_UDP_PROXY_FORWARDING_SUCCEEDED);
392 outgoingBs.Write(sata.senderClientAddress);
393 outgoingBs.Write(sata.targetClientAddress);
394 outgoingBs.Write(sata.targetClientGuid);
395 outgoingBs.Write(serverPublicIp);
396 outgoingBs.Write(forwardingPort);
397 rakPeerInterface->Send(&outgoingBs, MEDIUM_PRIORITY, RELIABLE_ORDERED, 0, fw->requestingAddress, false);
398
399 outgoingBs.Reset();
400 outgoingBs.Write((MessageID)ID_UDP_PROXY_GENERAL);
401 outgoingBs.Write((MessageID)ID_UDP_PROXY_FORWARDING_NOTIFICATION);
402 outgoingBs.Write(sata.senderClientAddress);
403 outgoingBs.Write(sata.targetClientAddress);
404 outgoingBs.Write(sata.targetClientGuid);
405 outgoingBs.Write(serverPublicIp);
406 outgoingBs.Write(forwardingPort);
407 rakPeerInterface->Send(&outgoingBs, MEDIUM_PRIORITY, RELIABLE_ORDERED, 0, sata.targetClientAddress, false);
408
409 // 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
410 fw->timeoutAfterSuccess= SLNet::GetTimeMS()+fw->timeoutOnNoDataMS;
411 // forwardingRequestList.RemoveAtIndex(index);
412 // SLNet::OP_DELETE(fw,_FILE_AND_LINE_);
413
414 return;
415 }
416 else if (success==UDPFORWARDER_NO_SOCKETS)
417 {
418 // Try next server
419 TryNextServer(sata, fw);
420 }
421 else
422 {
423 RakAssert(success==UDPFORWARDER_FORWARDING_ALREADY_EXISTS);
424
425 // Return in progress
426 outgoingBs.Write((MessageID)ID_UDP_PROXY_GENERAL);
427 outgoingBs.Write((MessageID)ID_UDP_PROXY_IN_PROGRESS);
428 outgoingBs.Write(sata.senderClientAddress);
429 outgoingBs.Write(sata.targetClientAddress);
430 outgoingBs.Write(sata.targetClientGuid);
431 outgoingBs.Write(serverPublicIp);
432 outgoingBs.Write(forwardingPort);
433 rakPeerInterface->Send(&outgoingBs, MEDIUM_PRIORITY, RELIABLE_ORDERED, 0, fw->requestingAddress, false);
434 forwardingRequestList.RemoveAtIndex(index);
435 SLNet::OP_DELETE(fw,_FILE_AND_LINE_);
436 }
437 }
438 void UDPProxyCoordinator::OnPingServersReplyFromClientToCoordinator(Packet *packet)
439 {
440 SLNet::BitStream incomingBs(packet->data, packet->length, false);
441 incomingBs.IgnoreBytes(2);
442 unsigned short serversToPingSize;
443 SystemAddress serverAddress;
444 SenderAndTargetAddress sata;
445 incomingBs.Read(sata.senderClientAddress);
446 incomingBs.Read(sata.targetClientAddress);
447 bool objectExists;
448 unsigned int index = forwardingRequestList.GetIndexFromKey(sata, &objectExists);
449 if (objectExists==false)
450 return;
451 unsigned short idx;
452 ServerWithPing swp;
453 ForwardingRequest *fw = forwardingRequestList[index];
454 if (fw->timeRequestedPings==0)
455 return;
456
457 incomingBs.Read(serversToPingSize);
458 if (packet->systemAddress==sata.senderClientAddress)
459 {
460 for (idx=0; idx < serversToPingSize; idx++)
461 {
462 incomingBs.Read(swp.serverAddress);
463 incomingBs.Read(swp.ping);
464 unsigned int index2;
465 for (index2=0; index2 < fw->sourceServerPings.Size(); index2++)
466 {
467 if (fw->sourceServerPings[index2].ping >= swp.ping )
468 break;
469 }
470 fw->sourceServerPings.Insert(swp, index2, _FILE_AND_LINE_);
471 }
472 }
473 else
474 {
475 for (idx=0; idx < serversToPingSize; idx++)
476 {
477 incomingBs.Read(swp.serverAddress);
478 incomingBs.Read(swp.ping);
479
480 unsigned int index2;
481 for (index2=0; index2 < fw->targetServerPings.Size(); index2++)
482 {
483 if (fw->targetServerPings[index2].ping >= swp.ping )
484 break;
485 }
486 fw->sourceServerPings.Insert(swp, index2, _FILE_AND_LINE_);
487 }
488 }
489
490 // Both systems have to give us pings to progress here. Otherwise will timeout in Update()
491 if (fw->sourceServerPings.Size()>0 &&
492 fw->targetServerPings.Size()>0)
493 {
494 fw->OrderRemainingServersToTry();
495 fw->timeRequestedPings=0;
496 TryNextServer(fw->sata, fw);
497 }
498 }
499 void UDPProxyCoordinator::TryNextServer(SenderAndTargetAddress sata, ForwardingRequest *fw)
500 {
501 bool pickedGoodServer=false;
502 while(fw->remainingServersToTry.Size()>0)
503 {
504 fw->currentlyAttemptedServerAddress=fw->remainingServersToTry.Pop();
505 if (serverList.GetIndexOf(fw->currentlyAttemptedServerAddress)!=(unsigned int)-1)
506 {
507 pickedGoodServer=true;
508 break;
509 }
510 }
511
512 if (pickedGoodServer==false)
513 {
514 SendAllBusy(sata.senderClientAddress, sata.targetClientAddress, sata.targetClientGuid, fw->requestingAddress);
515 forwardingRequestList.Remove(sata);
516 SLNet::OP_DELETE(fw,_FILE_AND_LINE_);
517 return;
518 }
519
520 SendForwardingRequest(sata.senderClientAddress, sata.targetClientAddress, fw->currentlyAttemptedServerAddress, fw->timeoutOnNoDataMS);
521 }
522 void UDPProxyCoordinator::SendAllBusy(SystemAddress senderClientAddress, SystemAddress targetClientAddress, RakNetGUID targetClientGuid, SystemAddress requestingAddress)
523 {
524 SLNet::BitStream outgoingBs;
525 outgoingBs.Write((MessageID)ID_UDP_PROXY_GENERAL);
526 outgoingBs.Write((MessageID)ID_UDP_PROXY_ALL_SERVERS_BUSY);
527 outgoingBs.Write(senderClientAddress);
528 outgoingBs.Write(targetClientAddress);
529 outgoingBs.Write(targetClientGuid);
530 rakPeerInterface->Send(&outgoingBs, MEDIUM_PRIORITY, RELIABLE_ORDERED, 0, requestingAddress, false);
531 }
532 void UDPProxyCoordinator::Clear(void)
533 {
534 serverList.Clear(true, _FILE_AND_LINE_);
535 for (unsigned int i=0; i < forwardingRequestList.Size(); i++)
536 {
537 SLNet::OP_DELETE(forwardingRequestList[i],_FILE_AND_LINE_);
538 }
539 forwardingRequestList.Clear(false, _FILE_AND_LINE_);
540 }
541 void UDPProxyCoordinator::ForwardingRequest::OrderRemainingServersToTry(void)
542 {
543 //DataStructures::Multilist<ML_ORDERED_LIST,UDPProxyCoordinator::ServerWithPing,unsigned short> swpList;
544 DataStructures::OrderedList<unsigned short, UDPProxyCoordinator::ServerWithPing, ServerWithPingComp> swpList;
545 // swpList.SetSortOrder(true);
546
547 if (sourceServerPings.Size()==0 && targetServerPings.Size()==0)
548 return;
549
550 unsigned int idx;
551 UDPProxyCoordinator::ServerWithPing swp;
552 for (idx=0; idx < remainingServersToTry.Size(); idx++)
553 {
554 swp.serverAddress=remainingServersToTry[idx];
555 swp.ping=0;
556 if (sourceServerPings.Size())
557 swp.ping+=(unsigned short) (sourceServerPings[idx].ping);
558 else
559 swp.ping+=(unsigned short) (DEFAULT_CLIENT_UNRESPONSIVE_PING_TIME);
560 if (targetServerPings.Size())
561 swp.ping+=(unsigned short) (targetServerPings[idx].ping);
562 else
563 swp.ping+=(unsigned short) (DEFAULT_CLIENT_UNRESPONSIVE_PING_TIME);
564 swpList.Insert(swp.ping, swp, false, _FILE_AND_LINE_);
565 }
566 remainingServersToTry.Clear(_FILE_AND_LINE_ );
567 for (idx=0; idx < swpList.Size(); idx++)
568 {
569 remainingServersToTry.Push(swpList[idx].serverAddress, _FILE_AND_LINE_ );
570 }
571 }
572
573 #endif // _RAKNET_SUPPORT_*