00001 #include "NativeFeatureIncludes.h"
00002 #if _RAKNET_SUPPORT_Router2==1
00003
00004 #include "Router2.h"
00005 #include "RakPeerInterface.h"
00006 #include "BitStream.h"
00007 #include "RakNetTime.h"
00008 #include "GetTime.h"
00009 #include "DS_OrderedList.h"
00010 #include "SocketLayer.h"
00011 #include "FormatString.h"
00012
00013 using namespace RakNet;
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041 void Router2DebugInterface::ShowFailure(const char *message)
00042 {
00043 printf(message);
00044 }
00045 void Router2DebugInterface::ShowDiagnostic(const char *message)
00046 {
00047 printf(message);
00048 }
00049
00050 enum Router2MessageIdentifiers
00051 {
00052 ID_ROUTER_2_QUERY_FORWARDING,
00053 ID_ROUTER_2_REPLY_FORWARDING,
00054 ID_ROUTER_2_REQUEST_FORWARDING,
00055 ID_ROUTER_2_INCREASE_TIMEOUT,
00056 };
00057 Router2::ConnnectRequest::ConnnectRequest()
00058 {
00059
00060 }
00061 Router2::ConnnectRequest::~ConnnectRequest()
00062 {
00063
00064 }
00065 Router2::Router2()
00066 {
00067 udpForwarder=0;
00068 maximumForwardingRequests=0;
00069 debugInterface=0;
00070 }
00071 Router2::~Router2()
00072 {
00073 ClearAll();
00074
00075 if (udpForwarder)
00076 {
00077 udpForwarder->Shutdown();
00078 RakNet::OP_DELETE(udpForwarder,__FILE__,__LINE__);
00079 }
00080 }
00081 void Router2::ClearMinipunches(void)
00082 {
00083 miniPunchesInProgress.Clear(false,__FILE__,__LINE__);
00084 }
00085 void Router2::ClearConnectionRequests(void)
00086 {
00087 for (unsigned int i=0; i < connectionRequests.Size(); i++)
00088 {
00089 RakNet::OP_DELETE(connectionRequests[i],__FILE__,__LINE__);
00090 }
00091 connectionRequests.Clear(false,__FILE__,__LINE__);
00092 }
00093 bool Router2::ConnectInternal(RakNetGUID endpointGuid, bool returnConnectionLostOnFailure)
00094 {
00095 int largestPing = GetLargestPingAmongConnectedSystems();
00096 if (largestPing<0)
00097 {
00098 char buff[512];
00099 if (debugInterface) debugInterface->ShowFailure(FormatStringTS(buff,"Router2 failed at %s:%i\n", __FILE__, __LINE__));
00100
00101
00102 return false;
00103 }
00104
00105
00106 if (GetConnectionRequestIndex(endpointGuid)!=(unsigned int)-1)
00107 {
00108 char buff[512];
00109 if (debugInterface) debugInterface->ShowFailure(FormatStringTS(buff,"Router2 failed at %s:%i\n", __FILE__, __LINE__));
00110
00111 return false;
00112 }
00113
00114
00115 Router2::ConnnectRequest *cr = RakNet::OP_NEW<Router2::ConnnectRequest>(__FILE__,__LINE__);
00116 DataStructures::List<SystemAddress> addresses;
00117 DataStructures::List<RakNetGUID> guids;
00118 rakPeerInterface->GetSystemList(addresses, guids);
00119 if (guids.Size()==0)
00120 {
00121 char buff[512];
00122 if (debugInterface) debugInterface->ShowFailure(FormatStringTS(buff,"Router2 failed at %s:%i\n", __FILE__, __LINE__));
00123
00124 return false;
00125 }
00126 cr->requestState=R2RS_REQUEST_STATE_QUERY_FORWARDING;
00127 cr->pingTimeout=RakNet::GetTimeMS()+largestPing*2+1000;
00128 cr->endpointGuid=endpointGuid;
00129 cr->returnConnectionLostOnFailure=returnConnectionLostOnFailure;
00130 for (unsigned int i=0; i < guids.Size(); i++)
00131 {
00132 ConnectionRequestSystem crs;
00133 if (guids[i]!=endpointGuid)
00134 {
00135 crs.guid=guids[i];
00136 crs.pingToEndpoint=-1;
00137 cr->connectionRequestSystems.Push(crs,__FILE__,__LINE__);
00138
00139
00140 RakNet::BitStream bsOut;
00141 bsOut.Write((MessageID)ID_ROUTER_2_INTERNAL);
00142 bsOut.Write((unsigned char) ID_ROUTER_2_QUERY_FORWARDING);
00143 bsOut.Write(endpointGuid);
00144 rakPeerInterface->Send(&bsOut,MEDIUM_PRIORITY,RELIABLE_ORDERED,0,crs.guid,false);
00145 }
00146 }
00147 connectionRequests.Push(cr,__FILE__,__LINE__);
00148
00149 if (debugInterface)
00150 {
00151 char buff[512];
00152 debugInterface->ShowDiagnostic(FormatStringTS(buff,"Broadcasting ID_ROUTER_2_QUERY_FORWARDING at %s:%i\n", __FILE__, __LINE__));
00153 }
00154
00155 return true;
00156 }
00157 void Router2::EstablishRouting(RakNetGUID endpointGuid)
00158 {
00159
00160 if (rakPeerInterface->IsConnected(endpointGuid,false,false)==true)
00161 {
00162 char buff[512];
00163 if (debugInterface) debugInterface->ShowFailure(FormatStringTS(buff,"Router2 failed at %s:%i (already connected)\n", __FILE__, __LINE__));
00164 return;
00165 }
00166
00167 ConnectInternal(endpointGuid,false);
00168 }
00169 void Router2::SetMaximumForwardingRequests(int max)
00170 {
00171 if (max>0 && maximumForwardingRequests<=0)
00172 {
00173 udpForwarder = RakNet::OP_NEW<UDPForwarder>(__FILE__,__LINE__);
00174 udpForwarder->Startup();
00175 }
00176 else if (max<=0 && maximumForwardingRequests>0)
00177 {
00178 udpForwarder->Shutdown();
00179 RakNet::OP_DELETE(udpForwarder,__FILE__,__LINE__);
00180 udpForwarder=0;
00181 }
00182
00183 maximumForwardingRequests=max;
00184 }
00185 PluginReceiveResult Router2::OnReceive(Packet *packet)
00186 {
00187 SystemAddress sa;
00188 RakNet::BitStream bs(packet->data,packet->length,false);
00189 if (packet->data[0]==ID_ROUTER_2_INTERNAL)
00190 {
00191 switch (packet->data[1])
00192 {
00193 case ID_ROUTER_2_QUERY_FORWARDING:
00194 {
00195 OnQueryForwarding(packet);
00196 return RR_STOP_PROCESSING_AND_DEALLOCATE;
00197 }
00198 case ID_ROUTER_2_REPLY_FORWARDING:
00199 {
00200 OnQueryForwardingReply(packet);
00201 return RR_STOP_PROCESSING_AND_DEALLOCATE;
00202 }
00203 case ID_ROUTER_2_REQUEST_FORWARDING:
00204 {
00205 OnRequestForwarding(packet);
00206 return RR_STOP_PROCESSING_AND_DEALLOCATE;
00207 }
00208 case ID_ROUTER_2_INCREASE_TIMEOUT:
00209 {
00211 rakPeerInterface->SetTimeoutTime(rakPeerInterface->GetTimeoutTime(packet->systemAddress)+10000, packet->systemAddress);
00212 return RR_STOP_PROCESSING_AND_DEALLOCATE;
00213 }
00214 }
00215 }
00216 else if (packet->data[0]==ID_OUT_OF_BAND_INTERNAL && packet->length>=2)
00217 {
00218 switch (packet->data[1])
00219 {
00220 case ID_ROUTER_2_REPLY_TO_SENDER_PORT:
00221 {
00222 RakNet::BitStream bsOut;
00223 bsOut.Write(packet->guid);
00224 SendOOBFromRakNetPort(ID_ROUTER_2_MINI_PUNCH_REPLY, &bsOut, packet->systemAddress);
00225
00226 if (debugInterface)
00227 {
00228 char buff[512];
00229 debugInterface->ShowDiagnostic(FormatStringTS(buff,"Got ID_ROUTER_2_REPLY_TO_SENDER_PORT, replying with ID_ROUTER_2_MINI_PUNCH_REPLY at %s:%i\n", __FILE__, __LINE__));
00230 }
00231
00232 return RR_STOP_PROCESSING_AND_DEALLOCATE;
00233 }
00234 case ID_ROUTER_2_REPLY_TO_SPECIFIED_PORT:
00235 {
00236 RakNet::BitStream bsOut;
00237 bsOut.Write(packet->guid);
00238 bs.IgnoreBytes(2);
00239 sa.binaryAddress=packet->systemAddress.binaryAddress;
00240 bs.Read(sa.port);
00241 RakAssert(sa.port!=0);
00242 SendOOBFromRakNetPort(ID_ROUTER_2_MINI_PUNCH_REPLY, &bsOut, sa);
00243
00244 if (debugInterface)
00245 {
00246 char buff[512];
00247 debugInterface->ShowDiagnostic(FormatStringTS(buff,"Got ID_ROUTER_2_REPLY_TO_SENDER_PORT, replying with ID_ROUTER_2_MINI_PUNCH_REPLY at %s:%i\n", __FILE__, __LINE__));
00248 }
00249
00250 return RR_STOP_PROCESSING_AND_DEALLOCATE;
00251 }
00252 case ID_ROUTER_2_MINI_PUNCH_REPLY:
00253 OnMiniPunchReply(packet);
00254 return RR_STOP_PROCESSING_AND_DEALLOCATE;
00255 case ID_ROUTER_2_MINI_PUNCH_REPLY_BOUNCE:
00256 OnMiniPunchReplyBounce(packet);
00257 return RR_STOP_PROCESSING_AND_DEALLOCATE;
00258 case ID_ROUTER_2_REROUTE:
00259 {
00260 OnReroute(packet);
00261 return RR_STOP_PROCESSING_AND_DEALLOCATE;
00262 }
00263 }
00264 }
00265 else if (packet->data[0]==ID_ROUTER_2_FORWARDING_ESTABLISHED)
00266 {
00267
00268 if (OnForwardingSuccess(packet)==false)
00269 return RR_STOP_PROCESSING_AND_DEALLOCATE;
00270 }
00271 else if (packet->data[0]==ID_CONNECTION_REQUEST_ACCEPTED)
00272 {
00273 unsigned int forwardingIndex;
00274 for (forwardingIndex=0; forwardingIndex < forwardedConnectionList.Size(); forwardingIndex++)
00275 {
00276 if (forwardedConnectionList[forwardingIndex].endpointGuid==packet->guid)
00277 break;
00278 }
00279
00280 if (forwardingIndex<forwardedConnectionList.Size())
00281 {
00282
00283
00284 RakNet::BitStream bsOut;
00285 bsOut.Write((MessageID)ID_ROUTER_2_INTERNAL);
00286 bsOut.Write((unsigned char) ID_ROUTER_2_INCREASE_TIMEOUT);
00287 rakPeerInterface->Send(&bsOut,HIGH_PRIORITY,RELIABLE,0,packet->guid,false);
00288
00289 if (debugInterface)
00290 {
00291 char buff[512];
00292 debugInterface->ShowDiagnostic(FormatStringTS(buff,"Got ID_CONNECTION_REQUEST_ACCEPTED, sending ID_ROUTER_2_INCREASE_TIMEOUT at %s:%i\n", __FILE__, __LINE__));
00293 }
00294
00295
00296 rakPeerInterface->SetTimeoutTime(rakPeerInterface->GetTimeoutTime(packet->systemAddress)+10000, packet->systemAddress);
00297 }
00298 }
00299
00300 return RR_CONTINUE_PROCESSING;
00301 }
00302 void Router2::Update(void)
00303 {
00304 RakNetTimeMS curTime = RakNet::GetTimeMS();
00305 unsigned int connectionRequestIndex=0;
00306 while (connectionRequestIndex < connectionRequests.Size())
00307 {
00308 ConnnectRequest* connectionRequest = connectionRequests[connectionRequestIndex];
00309
00310 if (connectionRequest->requestState==R2RS_REQUEST_STATE_QUERY_FORWARDING &&
00311 connectionRequest->pingTimeout < curTime)
00312 {
00313 bool anyRemoved=false;
00314 unsigned int connectionRequestGuidIndex=0;
00315 while (connectionRequestGuidIndex < connectionRequest->connectionRequestSystems.Size())
00316 {
00317 if (connectionRequest->connectionRequestSystems[connectionRequestGuidIndex].pingToEndpoint<0)
00318 {
00319 anyRemoved=true;
00320 connectionRequest->connectionRequestSystems.RemoveAtIndexFast(connectionRequestGuidIndex);
00321 }
00322 else
00323 {
00324 connectionRequestGuidIndex++;
00325 }
00326 }
00327
00328 if (anyRemoved)
00329 {
00330 if (UpdateForwarding(connectionRequestIndex)==false)
00331 {
00332 RemoveConnectionRequest(connectionRequestIndex);
00333 }
00334 else
00335 {
00336 connectionRequestIndex++;
00337 }
00338 }
00339 else
00340 {
00341 connectionRequestIndex++;
00342 }
00343 }
00344 else
00345 {
00346 connectionRequestIndex++;
00347 }
00348 }
00349
00350 unsigned int i=0;
00351 while (i < miniPunchesInProgress.Size())
00352 {
00353 if (miniPunchesInProgress[i].timeout<curTime)
00354 {
00355 SendFailureOnCannotForward(miniPunchesInProgress[i].sourceGuid, miniPunchesInProgress[i].endpointGuid);
00356 miniPunchesInProgress.RemoveAtIndexFast(i);
00357 }
00358 else if (curTime>miniPunchesInProgress[i].nextAction)
00359 {
00360 miniPunchesInProgress[i].nextAction=curTime+100;
00361 SendOOBMessages(&miniPunchesInProgress[i]);
00362 }
00363 else
00364 i++;
00365 }
00366
00367 }
00368 void Router2::OnClosedConnection(SystemAddress systemAddress, RakNetGUID rakNetGUID, PI2_LostConnectionReason lostConnectionReason )
00369 {
00370 (void) lostConnectionReason;
00371 (void) systemAddress;
00372
00373
00374 unsigned int forwardedConnectionIndex=0;
00375 while (forwardedConnectionIndex<forwardedConnectionList.Size())
00376 {
00377 if (forwardedConnectionList[forwardedConnectionIndex].endpointGuid==rakNetGUID)
00378 {
00379 if (debugInterface)
00380 {
00381 char buff[512];
00382 debugInterface->ShowDiagnostic(FormatStringTS(buff,"Closed connection, removing forwarding from list at %s:%i\n", __FILE__, __LINE__));
00383 }
00384
00385
00386 forwardedConnectionList.RemoveAtIndexFast(forwardedConnectionIndex);
00387 }
00388 else if (forwardedConnectionList[forwardedConnectionIndex].intermediaryGuid==rakNetGUID)
00389 {
00390
00391 ConnectInternal(forwardedConnectionList[forwardedConnectionIndex].endpointGuid, true);
00392
00393 forwardedConnectionIndex++;
00394
00395 if (debugInterface)
00396 {
00397 char buff[512];
00398 debugInterface->ShowDiagnostic(FormatStringTS(buff,"Closed connection, restarting forwarding at %s:%i\n", __FILE__, __LINE__));
00399 }
00400
00401
00402
00403 }
00404 else
00405 forwardedConnectionIndex++;
00406 }
00407
00408 unsigned int connectionRequestIndex=0;
00409 while (connectionRequestIndex < connectionRequests.Size())
00410 {
00411 unsigned int connectionRequestGuidIndex = connectionRequests[connectionRequestIndex]->GetGuidIndex(rakNetGUID);
00412 if (connectionRequestGuidIndex!=(unsigned int)-1)
00413 {
00414 connectionRequests[connectionRequestIndex]->connectionRequestSystems.RemoveAtIndexFast(connectionRequestGuidIndex);
00415 if (UpdateForwarding(connectionRequestIndex)==false)
00416 {
00417 if (debugInterface)
00418 {
00419 char buff[512];
00420 debugInterface->ShowDiagnostic(FormatStringTS(buff,"Aborted connection, aborted forwarding at %s:%i\n", __FILE__, __LINE__));
00421 }
00422
00423 RemoveConnectionRequest(connectionRequestIndex);
00424 }
00425 else
00426 {
00427 if (debugInterface)
00428 {
00429 char buff[512];
00430 debugInterface->ShowDiagnostic(FormatStringTS(buff,"Aborted connection, restarting forwarding at %s:%i\n", __FILE__, __LINE__));
00431 }
00432
00433 connectionRequestIndex++;
00434 }
00435 }
00436 else
00437 {
00438 connectionRequestIndex++;
00439 }
00440 }
00441
00442
00443 unsigned int i=0;
00444 while (i < miniPunchesInProgress.Size())
00445 {
00446 if (miniPunchesInProgress[i].sourceGuid==rakNetGUID || miniPunchesInProgress[i].endpointGuid==rakNetGUID)
00447 {
00448 if (miniPunchesInProgress[i].sourceGuid!=rakNetGUID)
00449 {
00450 SendFailureOnCannotForward(miniPunchesInProgress[i].sourceGuid, miniPunchesInProgress[i].endpointGuid);
00451 }
00452 miniPunchesInProgress.RemoveAtIndexFast(i);
00453 }
00454 else
00455 i++;
00456 }
00457 }
00458 void Router2::OnFailedConnectionAttempt(Packet *packet, PI2_FailedConnectionAttemptReason failedConnectionAttemptReason)
00459 {
00460 (void) failedConnectionAttemptReason;
00461 (void) packet;
00462
00463 unsigned int forwardedConnectionIndex=0;
00464 while (forwardedConnectionIndex<forwardedConnectionList.Size())
00465 {
00466 if (forwardedConnectionList[forwardedConnectionIndex].intermediaryAddress==packet->systemAddress)
00467 {
00468 if (debugInterface)
00469 {
00470 char buff[512];
00471 debugInterface->ShowDiagnostic(FormatStringTS(buff,"Failed connection attempt to forwarded system at %s:%i\n", __FILE__, __LINE__));
00472 }
00473
00474 packet->guid=forwardedConnectionList[forwardedConnectionIndex].endpointGuid;
00475 forwardedConnectionList.RemoveAtIndexFast(forwardedConnectionIndex);
00476 }
00477 else
00478 forwardedConnectionIndex++;
00479 }
00480 }
00481 void Router2::OnNewConnection(SystemAddress systemAddress, RakNetGUID rakNetGUID, bool isIncoming)
00482 {
00483 (void) isIncoming;
00484 (void) rakNetGUID;
00485 (void) systemAddress;
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495 }
00496 void Router2::OnRakPeerShutdown(void)
00497 {
00498 ClearAll();
00499 }
00500 bool Router2::UpdateForwarding(unsigned int connectionRequestIndex)
00501 {
00502 ConnnectRequest* connectionRequest = connectionRequests[connectionRequestIndex];
00503 if (connectionRequest->connectionRequestSystems.Size()==0)
00504 {
00505
00506 if (connectionRequest->returnConnectionLostOnFailure)
00507 ReturnToUser(ID_CONNECTION_LOST, connectionRequest->endpointGuid, UNASSIGNED_SYSTEM_ADDRESS);
00508 else
00509 ReturnToUser(ID_ROUTER_2_FORWARDING_NO_PATH, connectionRequest->endpointGuid, UNASSIGNED_SYSTEM_ADDRESS);
00510
00511 if (debugInterface)
00512 {
00513 char buff[512];
00514 debugInterface->ShowDiagnostic(FormatStringTS(buff,"Forwarding failed, no remaining systems at %s:%i\n", __FILE__, __LINE__));
00515 }
00516
00517 for (unsigned int forwardedConnectionIndex=0; forwardedConnectionIndex < forwardedConnectionList.Size(); forwardedConnectionIndex++)
00518 {
00519 if (forwardedConnectionList[forwardedConnectionIndex].endpointGuid==connectionRequest->endpointGuid)
00520 {
00521 forwardedConnectionList.RemoveAtIndexFast(forwardedConnectionIndex);
00522 break;
00523 }
00524 }
00525
00526 return false;
00527 }
00528
00529 if (connectionRequest->requestState==R2RS_REQUEST_STATE_QUERY_FORWARDING)
00530 {
00531 for (unsigned int i=0; i < connectionRequest->connectionRequestSystems.Size(); i++)
00532 {
00533 if (connectionRequest->connectionRequestSystems[i].pingToEndpoint<0)
00534 return true;
00535 }
00536
00537 RequestForwarding(connectionRequestIndex);
00538 }
00539
00540
00541
00542
00543
00544 return true;
00545 }
00546 void Router2::RemoveConnectionRequest(unsigned int connectionRequestIndex)
00547 {
00548 RakNet::OP_DELETE(connectionRequests[connectionRequestIndex],__FILE__,__LINE__);
00549 connectionRequests.RemoveAtIndexFast(connectionRequestIndex);
00550 }
00551 int ConnectionRequestSystemComp( const Router2::ConnectionRequestSystem & key, const Router2::ConnectionRequestSystem &data )
00552 {
00553 if (key.pingToEndpoint * (key.usedForwardingEntries+1) < data.pingToEndpoint * (data.usedForwardingEntries+1))
00554 return -1;
00555 if (key.pingToEndpoint * (key.usedForwardingEntries+1) == data.pingToEndpoint * (data.usedForwardingEntries+1))
00556 return 1;
00557 if (key.guid < data.guid)
00558 return -1;
00559 if (key.guid > data.guid)
00560 return -1;
00561 return 0;
00562 }
00563 void Router2::RequestForwarding(unsigned int connectionRequestIndex)
00564 {
00565 ConnnectRequest* connectionRequest = connectionRequests[connectionRequestIndex];
00566 RakAssert(connectionRequest->requestState==R2RS_REQUEST_STATE_QUERY_FORWARDING);
00567 connectionRequest->requestState=REQUEST_STATE_REQUEST_FORWARDING;
00568
00569 if (connectionRequest->GetGuidIndex(connectionRequest->lastRequestedForwardingSystem)!=(unsigned int)-1)
00570 {
00571 char buff[512];
00572 if (debugInterface) debugInterface->ShowFailure(FormatStringTS(buff,"Router2 failed at %s:%i\n", __FILE__, __LINE__));
00573 return;
00574 }
00575
00576
00577 DataStructures::OrderedList<ConnectionRequestSystem, ConnectionRequestSystem, ConnectionRequestSystemComp> commandList;
00578 unsigned int connectionRequestGuidIndex;
00579 for (connectionRequestGuidIndex=0; connectionRequestGuidIndex < connectionRequest->connectionRequestSystems.Size(); connectionRequestGuidIndex++)
00580 {
00581 RakAssert(connectionRequest->connectionRequestSystems[connectionRequestGuidIndex].pingToEndpoint>=0);
00582 commandList.Insert(connectionRequest->connectionRequestSystems[connectionRequestGuidIndex],
00583 connectionRequest->connectionRequestSystems[connectionRequestGuidIndex],
00584 true,
00585 __FILE__,
00586 __LINE__);
00587 }
00588
00589 connectionRequest->lastRequestedForwardingSystem=commandList[0].guid;
00590
00591 RakNet::BitStream bsOut;
00592 bsOut.Write((MessageID)ID_ROUTER_2_INTERNAL);
00593 bsOut.Write((unsigned char) ID_ROUTER_2_REQUEST_FORWARDING);
00594 bsOut.Write(connectionRequest->endpointGuid);
00595 rakPeerInterface->Send(&bsOut,MEDIUM_PRIORITY,RELIABLE_ORDERED,0,connectionRequest->lastRequestedForwardingSystem,false);
00596
00597 if (debugInterface)
00598 {
00599 char buff[512];
00600 debugInterface->ShowDiagnostic(FormatStringTS(buff,"Sending ID_ROUTER_2_REQUEST_FORWARDING at %s:%i\n", __FILE__, __LINE__));
00601 }
00602 }
00603 void Router2::SendFailureOnCannotForward(RakNetGUID sourceGuid, RakNetGUID endpointGuid)
00604 {
00605 RakNet::BitStream bsOut;
00606 bsOut.Write((MessageID)ID_ROUTER_2_INTERNAL);
00607 bsOut.Write((unsigned char) ID_ROUTER_2_REPLY_FORWARDING);
00608 bsOut.Write(endpointGuid);
00609 bsOut.Write(false);
00610 rakPeerInterface->Send(&bsOut,MEDIUM_PRIORITY,RELIABLE_ORDERED,0,sourceGuid,false);
00611 }
00612 int Router2::ReturnFailureOnCannotForward(RakNetGUID sourceGuid, RakNetGUID endpointGuid)
00613 {
00614
00615 if (udpForwarder==0 || udpForwarder->GetUsedForwardEntries()/2>maximumForwardingRequests)
00616 {
00617 char buff[512];
00618 if (debugInterface) debugInterface->ShowFailure(FormatStringTS(buff,"Router2 failed at %s:%i\n", __FILE__, __LINE__));
00619 SendFailureOnCannotForward(sourceGuid,endpointGuid);
00620 return -1;
00621 }
00622
00623 int pingToEndpoint;
00624 pingToEndpoint = rakPeerInterface->GetAveragePing(endpointGuid);
00625 if (pingToEndpoint==-1)
00626 {
00627 char buff[512];
00628 if (debugInterface) debugInterface->ShowFailure(FormatStringTS(buff,"Router2 failed at %s:%i\n", __FILE__, __LINE__));
00629 SendFailureOnCannotForward(sourceGuid,endpointGuid);
00630 return -1;
00631 }
00632 return pingToEndpoint;
00633 }
00634 void Router2::OnQueryForwarding(Packet *packet)
00635 {
00636 RakNet::BitStream bs(packet->data, packet->length, false);
00637 bs.IgnoreBytes(sizeof(MessageID) + sizeof(unsigned char));
00638 RakNetGUID endpointGuid;
00639
00640 bs.Read(endpointGuid);
00641
00642 int pingToEndpoint = ReturnFailureOnCannotForward(packet->guid, endpointGuid);
00643 if (pingToEndpoint==-1)
00644 {
00645 char buff[512];
00646 if (debugInterface) debugInterface->ShowFailure(FormatStringTS(buff,"Router2 failed at %s:%i\n", __FILE__, __LINE__));
00647 return;
00648 }
00649
00650
00651 RakNet::BitStream bsOut;
00652 bsOut.Write((MessageID)ID_ROUTER_2_INTERNAL);
00653 bsOut.Write((unsigned char) ID_ROUTER_2_REPLY_FORWARDING);
00654 bsOut.Write(endpointGuid);
00655 bsOut.Write(true);
00656 bsOut.Write((unsigned short) pingToEndpoint);
00657 bsOut.Write((unsigned short) udpForwarder->GetUsedForwardEntries()/2);
00658 rakPeerInterface->Send(&bsOut,MEDIUM_PRIORITY,RELIABLE_ORDERED,0,packet->guid,false);
00659
00660 if (debugInterface)
00661 {
00662 char buff[512];
00663 debugInterface->ShowDiagnostic(FormatStringTS(buff,"Sending ID_ROUTER_2_REPLY_FORWARDING at %s:%i\n", __FILE__, __LINE__));
00664 }
00665 }
00666 void Router2::OnQueryForwardingReply(Packet *packet)
00667 {
00668 RakNet::BitStream bs(packet->data, packet->length, false);
00669 bs.IgnoreBytes(sizeof(MessageID) + sizeof(unsigned char));
00670 RakNetGUID endpointGuid;
00671 bs.Read(endpointGuid);
00672
00673
00674 unsigned int connectionRequestIndex = GetConnectionRequestIndex(endpointGuid);
00675 if (connectionRequestIndex==(unsigned int)-1)
00676 {
00677 char buff[512];
00678 if (debugInterface) debugInterface->ShowFailure(FormatStringTS(buff,"Router2 failed at %s:%i\n", __FILE__, __LINE__));
00679 return;
00680 }
00681 unsigned int connectionRequestGuidIndex = connectionRequests[connectionRequestIndex]->GetGuidIndex(packet->guid);
00682 if (connectionRequestGuidIndex==(unsigned int)-1)
00683 {
00684 char buff[512];
00685 if (debugInterface) debugInterface->ShowFailure(FormatStringTS(buff,"Router2 failed at %s:%i\n", __FILE__, __LINE__));
00686 return;
00687 }
00688
00689 bool canForward;
00690 bs.Read(canForward);
00691
00692 if (debugInterface)
00693 {
00694 char buff[512];
00695 debugInterface->ShowDiagnostic(FormatStringTS(buff,"Got ID_ROUTER_2_REPLY_FORWARDING, canForward=%i at %s:%i\n", canForward, __FILE__, __LINE__));
00696 }
00697
00698 if (canForward)
00699 {
00700 unsigned short pingToEndpoint;
00701 unsigned short usedEntries;
00702 bs.Read(pingToEndpoint);
00703 bs.Read(usedEntries);
00704 connectionRequests[connectionRequestIndex]->connectionRequestSystems[connectionRequestGuidIndex].usedForwardingEntries=usedEntries;
00705 connectionRequests[connectionRequestIndex]->connectionRequestSystems[connectionRequestGuidIndex].pingToEndpoint=rakPeerInterface->GetAveragePing(packet->guid)+pingToEndpoint;
00706 }
00707 else
00708 {
00709 connectionRequests[connectionRequestIndex]->connectionRequestSystems.RemoveAtIndex(connectionRequestGuidIndex);
00710 }
00711
00712 if (UpdateForwarding(connectionRequestIndex)==false)
00713 {
00714 RemoveConnectionRequest(connectionRequestIndex);
00715 }
00716 }
00717 void Router2::SendForwardingSuccess(RakNetGUID sourceGuid, RakNetGUID endpointGuid, unsigned short sourceToDstPort)
00718 {
00719 RakNet::BitStream bsOut;
00720 bsOut.Write((MessageID) ID_ROUTER_2_FORWARDING_ESTABLISHED);
00721 bsOut.Write(endpointGuid);
00722 bsOut.Write(sourceToDstPort);
00723 rakPeerInterface->Send(&bsOut,MEDIUM_PRIORITY,RELIABLE_ORDERED,0,sourceGuid,false);
00724
00725 if (debugInterface)
00726 {
00727 char buff[512];
00728 debugInterface->ShowDiagnostic(FormatStringTS(buff,"Sending ID_ROUTER_2_FORWARDING_ESTABLISHED at %s:%i\n", __FILE__, __LINE__));
00729 }
00730 }
00731 void Router2::SendOOBFromRakNetPort(OutOfBandIdentifiers oob, BitStream *extraData, SystemAddress sa)
00732 {
00733 RakNet::BitStream oobBs;
00734 oobBs.Write((unsigned char)oob);
00735 if (extraData)
00736 {
00737 extraData->ResetReadPointer();
00738 oobBs.Write(*extraData);
00739 }
00740 char ipAddressString[32];
00741 sa.ToString(false, ipAddressString);
00742 rakPeerInterface->SendOutOfBand((const char*) ipAddressString,sa.port,(const char*) oobBs.GetData(),oobBs.GetNumberOfBytesUsed());
00743 }
00744 void Router2::SendOOBFromSpecifiedSocket(OutOfBandIdentifiers oob, SystemAddress sa, SOCKET socket)
00745 {
00746 RakNet::BitStream bs;
00747 rakPeerInterface->WriteOutOfBandHeader(&bs);
00748 bs.Write((unsigned char) oob);
00749 SocketLayer::Instance()->SendTo_PC( socket, (const char*) bs.GetData(), bs.GetNumberOfBytesUsed(), sa.binaryAddress, sa.port );
00750 }
00751 void Router2::SendOOBMessages(Router2::MiniPunchRequest *mpr)
00752 {
00753
00754
00755 SendOOBFromSpecifiedSocket(ID_ROUTER_2_REPLY_TO_SENDER_PORT, mpr->sourceAddress, mpr->destToSourceSocket);
00756
00757
00758 SendOOBFromSpecifiedSocket(ID_ROUTER_2_REPLY_TO_SENDER_PORT, mpr->endpointAddress, mpr->srcToDestSocket);
00759
00760
00761 RakNet::BitStream extraData;
00762 extraData.Write(mpr->srcToDestPort);
00763 RakAssert(mpr->srcToDestPort!=0);
00764 SendOOBFromRakNetPort(ID_ROUTER_2_REPLY_TO_SPECIFIED_PORT, &extraData, mpr->sourceAddress);
00765
00766
00767 extraData.Reset();
00768 extraData.Write(mpr->destToSourcePort);
00769 RakAssert(mpr->destToSourcePort);
00770 SendOOBFromRakNetPort(ID_ROUTER_2_REPLY_TO_SPECIFIED_PORT, &extraData, mpr->endpointAddress);
00771 }
00772 void Router2::OnReroute(Packet *packet)
00773 {
00774 RakNet::BitStream bs(packet->data, packet->length, false);
00775 bs.IgnoreBytes(sizeof(MessageID) + sizeof(unsigned char));
00776 RakNetGUID sourceGuid;
00777 bs.Read(sourceGuid);
00778
00779
00780 char ip[64];
00781
00782 packet->systemAddress.ToString(true,ip);
00783
00784
00785 rakPeerInterface->ChangeSystemAddress(sourceGuid,packet->systemAddress);
00786
00787 if (debugInterface)
00788 {
00789 char buff[512];
00790 debugInterface->ShowDiagnostic(FormatStringTS(buff,"Calling RakPeer::ChangeSystemAddress at %s:%i\n", __FILE__, __LINE__));
00791 }
00792 }
00793 void Router2::OnRequestForwarding(Packet *packet)
00794 {
00795 RakNet::BitStream bs(packet->data, packet->length, false);
00796 bs.IgnoreBytes(sizeof(MessageID) + sizeof(unsigned char));
00797 RakNetGUID endpointGuid;
00798 bs.Read(endpointGuid);
00799
00800 int pingToEndpoint = ReturnFailureOnCannotForward(packet->guid, endpointGuid);
00801 if (pingToEndpoint==-1)
00802 {
00803 char buff[512];
00804 if (debugInterface) debugInterface->ShowFailure(FormatStringTS(buff,"Router2 failed at %s:%i\n", __FILE__, __LINE__));
00805 return;
00806 }
00807
00808 unsigned short srcToDestPort;
00809 unsigned short destToSourcePort;
00810 SOCKET srcToDestSocket;
00811 SOCKET destToSourceSocket;
00812 SystemAddress endpointSystemAddress = rakPeerInterface->GetSystemAddressFromGuid(endpointGuid);
00813 UDPForwarderResult result = udpForwarder->StartForwarding(
00814 packet->systemAddress, endpointSystemAddress, 10000, 0,
00815 &srcToDestPort, &destToSourcePort, &srcToDestSocket, &destToSourceSocket);
00816
00817 if (result==UDPFORWARDER_FORWARDING_ALREADY_EXISTS)
00818 {
00819 if (debugInterface)
00820 {
00821 char buff[512];
00822 debugInterface->ShowDiagnostic(FormatStringTS(buff,"Got ID_ROUTER_2_REQUEST_FORWARDING, result=UDPFORWARDER_FORWARDING_ALREADY_EXISTS at %s:%i\n", __FILE__, __LINE__));
00823 }
00824
00825 SendForwardingSuccess(packet->guid, endpointGuid, srcToDestPort);
00826 }
00827 else if (result==UDPFORWARDER_NO_SOCKETS || result==UDPFORWARDER_INVALID_PARAMETERS)
00828 {
00829 char buff[512];
00830 if (debugInterface) debugInterface->ShowFailure(FormatStringTS(buff,"Router2 failed at %s:%i\n", __FILE__, __LINE__));
00831 RakAssert(result!=UDPFORWARDER_INVALID_PARAMETERS);
00832 SendFailureOnCannotForward(packet->guid, endpointGuid);
00833 }
00834 else
00835 {
00836 if (debugInterface)
00837 {
00838 char buff[512];
00839 debugInterface->ShowDiagnostic(FormatStringTS(buff,"Got ID_ROUTER_2_REQUEST_FORWARDING, calling SendOOBMessages at %s:%i\n", __FILE__, __LINE__));
00840 }
00841
00842
00843 MiniPunchRequest miniPunchRequest;
00844 miniPunchRequest.endpointAddress=endpointSystemAddress;
00845 miniPunchRequest.endpointGuid=endpointGuid;
00846 miniPunchRequest.gotReplyFromEndpoint=false;
00847 miniPunchRequest.gotReplyFromSource=false;
00848 miniPunchRequest.sourceGuid=packet->guid;
00849 miniPunchRequest.sourceAddress=packet->systemAddress;
00850 miniPunchRequest.srcToDestPort=srcToDestPort;
00851 miniPunchRequest.destToSourcePort=destToSourcePort;
00852 miniPunchRequest.srcToDestSocket=srcToDestSocket;
00853 miniPunchRequest.destToSourceSocket=destToSourceSocket;
00854 int ping1 = rakPeerInterface->GetAveragePing(packet->guid);
00855 int ping2 = rakPeerInterface->GetAveragePing(endpointGuid);
00856 if (ping1>ping2)
00857 miniPunchRequest.timeout=RakNet::GetTimeMS()+ping1*8+300;
00858 else
00859 miniPunchRequest.timeout=RakNet::GetTimeMS()+ping2*8+300;
00860 miniPunchRequest.nextAction=RakNet::GetTimeMS()+100;
00861 SendOOBMessages(&miniPunchRequest);
00862 miniPunchesInProgress.Push(miniPunchRequest,__FILE__,__LINE__);
00863 }
00864 }
00865 void Router2::OnMiniPunchReplyBounce(Packet *packet)
00866 {
00867
00868 unsigned int i=0;
00869 while (i < miniPunchesInProgress.Size())
00870 {
00871 if (miniPunchesInProgress[i].sourceGuid==packet->guid || miniPunchesInProgress[i].endpointGuid==packet->guid)
00872 {
00873 if (miniPunchesInProgress[i].sourceGuid==packet->guid)
00874 miniPunchesInProgress[i].gotReplyFromSource=true;
00875 if (miniPunchesInProgress[i].endpointGuid==packet->guid)
00876 miniPunchesInProgress[i].gotReplyFromEndpoint=true;
00877
00878 if (debugInterface)
00879 {
00880 char buff[512];
00881 debugInterface->ShowDiagnostic(FormatStringTS(buff,"Got ID_ROUTER_2_MINI_PUNCH_REPLY_BOUNCE, gotReplyFromSource=%i gotReplyFromEndpoint=%i at %s:%i\n", miniPunchesInProgress[i].gotReplyFromSource, miniPunchesInProgress[i].gotReplyFromEndpoint, __FILE__, __LINE__));
00882 }
00883
00884 if (miniPunchesInProgress[i].gotReplyFromEndpoint==true &&
00885 miniPunchesInProgress[i].gotReplyFromSource==true)
00886 {
00887 RakNet::BitStream bs;
00888 rakPeerInterface->WriteOutOfBandHeader(&bs);
00889 bs.Write((unsigned char) ID_ROUTER_2_REROUTE);
00890 bs.Write(miniPunchesInProgress[i].sourceGuid);
00891 SocketLayer::Instance()->SendTo_PC( miniPunchesInProgress[i].srcToDestSocket, (const char*) bs.GetData(), bs.GetNumberOfBytesUsed(), miniPunchesInProgress[i].endpointAddress.binaryAddress, miniPunchesInProgress[i].endpointAddress.port );
00892
00893 SendForwardingSuccess(miniPunchesInProgress[i].sourceGuid, miniPunchesInProgress[i].endpointGuid, miniPunchesInProgress[i].srcToDestPort);
00894 miniPunchesInProgress.RemoveAtIndexFast(i);
00895 }
00896 else
00897 {
00898 i++;
00899 }
00900 }
00901 else
00902 i++;
00903 }
00904 }
00905 void Router2::OnMiniPunchReply(Packet *packet)
00906 {
00907 RakNet::BitStream bs(packet->data, packet->length, false);
00908 bs.IgnoreBytes(sizeof(MessageID) + sizeof(unsigned char));
00909 RakNetGUID routerGuid;
00910 bs.Read(routerGuid);
00911 SendOOBFromRakNetPort(ID_ROUTER_2_MINI_PUNCH_REPLY_BOUNCE, 0, rakPeerInterface->GetSystemAddressFromGuid(routerGuid));
00912
00913 if (debugInterface)
00914 {
00915 char buff[512];
00916 debugInterface->ShowDiagnostic(FormatStringTS(buff,"Sending ID_ROUTER_2_MINI_PUNCH_REPLY_BOUNCE at %s:%i\n", __FILE__, __LINE__));
00917 }
00918 }
00919 bool Router2::OnForwardingSuccess(Packet *packet)
00920 {
00921 RakNet::BitStream bs(packet->data, packet->length, false);
00922 bs.IgnoreBytes(sizeof(MessageID));
00923 RakNetGUID endpointGuid;
00924 bs.Read(endpointGuid);
00925 unsigned short sourceToDestPort;
00926 bs.Read(sourceToDestPort);
00927
00928 unsigned int forwardingIndex;
00929 for (forwardingIndex=0; forwardingIndex < forwardedConnectionList.Size(); forwardingIndex++)
00930 {
00931 if (forwardedConnectionList[forwardingIndex].endpointGuid==endpointGuid)
00932 break;
00933 }
00934
00935 if (forwardingIndex<forwardedConnectionList.Size())
00936 {
00937
00938 SystemAddress intermediaryAddress=packet->systemAddress;
00939 intermediaryAddress.port=sourceToDestPort;
00940 rakPeerInterface->ChangeSystemAddress(endpointGuid, intermediaryAddress);
00941
00942 if (debugInterface)
00943 {
00944 char buff[512];
00945 debugInterface->ShowDiagnostic(FormatStringTS(buff,"Got ID_ROUTER_2_FORWARDING_ESTABLISHED, returning ID_ROUTER_2_REROUTED, Calling RakPeer::ChangeSystemAddress at %s:%i\n", __FILE__, __LINE__));
00946 }
00947
00948 packet->data[0]=ID_ROUTER_2_REROUTED;
00949
00950 return true;
00951 }
00952 else
00953 {
00954
00955 unsigned int connectionRequestIndex = GetConnectionRequestIndex(endpointGuid);
00956
00957 ForwardedConnection fc;
00958 fc.endpointGuid=endpointGuid;
00959 fc.intermediaryAddress=packet->systemAddress;
00960 fc.intermediaryAddress.port=sourceToDestPort;
00961 fc.intermediaryGuid=packet->guid;
00962 fc.returnConnectionLostOnFailure=connectionRequests[connectionRequestIndex]->returnConnectionLostOnFailure;
00963
00964 forwardedConnectionList.Push (fc,__FILE__,__LINE__);
00965
00966 if (debugInterface)
00967 {
00968 char buff[512];
00969 debugInterface->ShowDiagnostic(FormatStringTS(buff,"Got and returning to user ID_ROUTER_2_FORWARDING_ESTABLISHED at %s:%i\n", __FILE__, __LINE__));
00970 }
00971
00972 connectionRequests.RemoveAtIndexFast(connectionRequestIndex);
00973 }
00974 return true;
00975 }
00976 int Router2::GetLargestPingAmongConnectedSystems(void) const
00977 {
00978 int avePing;
00979 int largestPing=-1;
00980 unsigned short maxPeers = rakPeerInterface->GetMaximumNumberOfPeers();
00981 if (maxPeers==0)
00982 return 9999;
00983 unsigned short index;
00984 for (index=0; index < rakPeerInterface->GetMaximumNumberOfPeers(); index++)
00985 {
00986 RakNetGUID g = rakPeerInterface->GetGUIDFromIndex(index);
00987 if (g!=UNASSIGNED_RAKNET_GUID)
00988 {
00989 avePing=rakPeerInterface->GetAveragePing(rakPeerInterface->GetGUIDFromIndex(index));
00990 if (avePing>largestPing)
00991 largestPing=avePing;
00992 }
00993 }
00994 return largestPing;
00995 }
00996
00997 unsigned int Router2::GetConnectionRequestIndex(RakNetGUID endpointGuid)
00998 {
00999 unsigned int i;
01000 for (i=0; i < connectionRequests.Size(); i++)
01001 {
01002 if (connectionRequests[i]->endpointGuid==endpointGuid)
01003 return i;
01004 }
01005 return (unsigned int) -1;
01006 }
01007 unsigned int Router2::ConnnectRequest::GetGuidIndex(RakNetGUID guid)
01008 {
01009 unsigned int i;
01010 for (i=0; i < connectionRequestSystems.Size(); i++)
01011 {
01012 if (connectionRequestSystems[i].guid==guid)
01013 return i;
01014 }
01015 return (unsigned int) -1;
01016 }
01017 void Router2::ReturnToUser(MessageID messageId, RakNetGUID endpointGuid, SystemAddress systemAddress)
01018 {
01019 Packet *p = rakPeerInterface->AllocatePacket(sizeof(MessageID)+sizeof(unsigned char));
01020 p->data[0]=messageId;
01021 p->systemAddress=systemAddress;
01022 p->systemAddress.systemIndex=(SystemIndex)-1;
01023 p->guid=endpointGuid;
01024 rakPeerInterface->PushBackPacket(p, true);
01025 }
01026 void Router2::ClearForwardedConnections(void)
01027 {
01028 forwardedConnectionList.Clear(false,__FILE__,__LINE__);
01029 }
01030 void Router2::ClearAll(void)
01031 {
01032 ClearConnectionRequests();
01033 ClearMinipunches();
01034 ClearForwardedConnections();
01035 }
01036 void Router2::SetDebugInterface(Router2DebugInterface *_debugInterface)
01037 {
01038 debugInterface=_debugInterface;
01039 }
01040 Router2DebugInterface *Router2::GetDebugInterface(void) const
01041 {
01042 return debugInterface;
01043 }
01044
01045 #endif // _RAKNET_SUPPORT_*