• Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

Router2.cpp

Go to the documentation of this file.
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 Algorithm:
00017 
00018 1. Sender calls ConnectInternal(). A ConnnectRequest structure is allocated and stored in the connectionRequests list, containing a list of every system we are connected to. ID_ROUTER_2_QUERY_FORWARDING is sent to all connected systems.
00019 
00020 2. Upon the router getting ID_ROUTER_2_QUERY_FORWARDING, ID_ROUTER_2_REPLY_FORWARDING is sent to the sender indicating if that router is connected to the endpoint, along with the ping from the router to the endpoint.
00021 
00022 3. Upon the sender getting ID_ROUTER_2_REPLY_FORWARDING, the connection request structure is looked up in Router2::UpdateForwarding. The ping is stored in that structure. Once all systems have replied, the system continues to the next state. If every system in step 1 has been exhausted, and routing has occured at least once, then ID_CONNECTION_LOST is returned. If every system in step 1 has been exhausted and routing has never occured, then ID_ROUTER_2_FORWARDING_NO_PATH is returned. Otherwise, the router with the lowest ping is chosen, and RequestForwarding() is called with that system, which sends ID_ROUTER_2_REQUEST_FORWARDING to the router.
00023 
00024 4. When the router gets ID_ROUTER_2_REQUEST_FORWARDING, a MiniPunchRequest structure is allocated and stored in the miniPunchesInProgress list. The function SendOOBMessages() sends ID_ROUTER_2_REPLY_TO_SENDER_PORT from the routing sockets to both the sender and endpoint. It also sends ID_ROUTER_2_REPLY_TO_SPECIFIED_PORT through the regular RakNet connection.
00025 
00026 5. The sender and endpoint should get ID_ROUTER_2_REPLY_TO_SENDER_PORT and/or ID_ROUTER_2_REPLY_TO_SPECIFIED_PORT depending on what type of router they have. If ID_ROUTER_2_REPLY_TO_SENDER_PORT arrives, then this will reply back to the routing socket directly. If ID_ROUTER_2_REPLY_TO_SPECIFIED_PORT arrives, then the reply port is modified to be the port specified by the router system. In both cases, ID_ROUTER_2_MINI_PUNCH_REPLY is sent. As the router has already setup the forwarding, ID_ROUTER_2_MINI_PUNCH_REPLY will actually arrive to the endpoint from the sender, and from the sender to the endpoint.
00027 
00028 6. When ID_ROUTER_2_MINI_PUNCH_REPLY arrives, ID_ROUTER_2_MINI_PUNCH_REPLY_BOUNCE will be sent to the router. This is to tell the router that the forwarding has succeeded.
00029 
00030 7. When ID_ROUTER_2_MINI_PUNCH_REPLY_BOUNCE arrives on the router, the router will find the two systems in the miniPunchesInProgress list, which was added in step 4 (See OnMiniPunchReplyBounce()). gotReplyFromSource or gotReplyFromEndpoint will be set to true, depending on the sender. When both gotReplyFromSource and gotReplyFromEndpoint have replied, then ID_ROUTER_2_REROUTE is sent to the endpoint, and ID_ROUTER_2_FORWARDING_ESTABLISHED is sent to the sender.
00031 
00032 8. When the endpoint gets ID_ROUTER_2_REROUTE, the system address is updated for the guid of the sender using RakPeer::ChangeSystemAddress(). This happens in OnReroute().
00033 
00034 9. When the sender gets ID_ROUTER_2_FORWARDING_ESTABLISHED, then in OnForwardingSuccess() the endpoint is removed from the connectionRequest list and moved to the forwardedConnectionList.
00035 
00036 10. In OnClosedConnection(), for the sender, if the closed connection is the endpoint, then the endpoint is removed from the forwardedConnectionList (this is a graceful disconnect). If the connection was instead lost to the router, then ConnectInternal() gets called, which goes back to step 1. If instead this was a connection requset in progress, then UpdateForwarding() gets called, which goes back to step 3.
00037 
00038 11. When the user connects the endpoint and sender, then the sender will get ID_CONNECTION_REQUEST_ACCEPTED. The sender will look up the endpoint in the forwardedConnectionList, and send ID_ROUTER_2_INCREASE_TIMEOUT to the endpoint. This message will call SetTimeoutTime() on the endpoint, so that if the router disconnects, enough time is available for the reroute to complete.
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                 // Not connected to anyone
00102                 return false;
00103         }
00104 
00105         // ALready in progress?
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         // StoreRequest(endpointGuid, Largest(ping*2), systemsSentTo). Set state REQUEST_STATE_QUERY_FORWARDING
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                         // Broadcast(ID_ROUTER_2_QUERY_FORWARDING, endpointGuid);
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         // if (alreadyConnected to endpointGuid) Return false
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 //              printf("Got ID_ROUTER_2_FORWARDING_ESTABLISHED\n");
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                         // We connected to this system through a forwarding system
00283                         // Have the endpoint take longer to drop us, in case the intermediary system drops
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                         // Also take longer ourselves
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                 // pingTimeout is only used with R2RS_REQUEST_STATE_QUERY_FORWARDING
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                         // No longer need forwarding
00386                         forwardedConnectionList.RemoveAtIndexFast(forwardedConnectionIndex);
00387                 }
00388                 else if (forwardedConnectionList[forwardedConnectionIndex].intermediaryGuid==rakNetGUID)
00389                 {
00390                         // Lost connection to intermediary. Restart process to connect to endpoint. If failed, push ID_CONNECTION_LOST
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                         // This should not be removed - the connection is still forwarded, but perhaps through another system
00402 //                      forwardedConnectionList.RemoveAtIndexFast(forwardedConnectionIndex);
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 //      unsigned int forwardedConnectionIndex=0;
00488 //      while (forwardedConnectionIndex<forwardedConnectionList.Size())
00489 //      {
00490 //              // Never timeout forwarded connections. They fail if we lose the connection and can't reestablish
00491 // //           if (forwardedConnectionList[forwardedConnectionIndex].endpointGuid==rakNetGUID)
00492 // //                   rakPeerInterface->SetTimeoutTime(1000000, systemAddress);
00493 //              forwardedConnectionIndex++;
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         //      printf("Router2 failed at %s:%i\n", __FILE__, __LINE__);
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 //      else if (connectionRequest->requestState==REQUEST_STATE_REQUEST_FORWARDING)
00540 //      {
00541 //              RequestForwarding(connectionRequestIndex);
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         // Prioritize systems to request forwarding
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         // If the number of systems we are currently forwarding>=maxForwarding, return ID_ROUTER_2_REPLY_FORWARDING,endpointGuid,false
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         // Read endpointGuid
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         // If we are connected to endpointGuid, reply ID_ROUTER_2_REPLY_FORWARDING,endpointGuid,true,ping,numCurrentlyForwarding
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         // Find endpointGuid among stored requests
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         // Mini NAT punch
00754         // Send from srcToDestPort to packet->systemAddress (source). If the message arrives, the remote system should reply.
00755         SendOOBFromSpecifiedSocket(ID_ROUTER_2_REPLY_TO_SENDER_PORT, mpr->sourceAddress, mpr->destToSourceSocket);
00756 
00757         // Send from destToSourcePort to endpointSystemAddress (destination). If the message arrives, the remote system should reply.
00758         SendOOBFromSpecifiedSocket(ID_ROUTER_2_REPLY_TO_SENDER_PORT, mpr->endpointAddress, mpr->srcToDestSocket);
00759 
00760         // Tell source to send to srcToDestPort
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         // Tell destination to send to destToSourcePort
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 //      char address[64];
00780         char ip[64];
00781 //      sourceGuid.ToString(address);
00782         packet->systemAddress.ToString(true,ip);
00783 //      printf("Rerouting source guid %s to address %s\n", address, ip);
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                 // Store the punch request
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         // Find stored punch request
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                 // Return rerouted notice
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; // Return packet to user
00951         }
00952         else
00953         {
00954                 // removeFrom connectionRequests;
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                 // add to forwarding list
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; // Return packet to user
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_*

Generated on Thu Sep 30 2010 01:27:28 for RakNet by  doxygen 1.7.1