UDPProxyCoordinator.cpp 21 KB

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