| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624 |
- /*
- * Copyright (c) 2014, Oculus VR, Inc.
- * All rights reserved.
- *
- * This source code is licensed under the BSD-style license found in the
- * LICENSE file in the root directory of this source tree. An additional grant
- * of patent rights can be found in the PATENTS file in the same directory.
- *
- */
- #include "NativeFeatureIncludes.h"
- #if _RAKNET_SUPPORT_NatPunchthroughServer==1
- #include "NatPunchthroughServer.h"
- #include "SocketLayer.h"
- #include "BitStream.h"
- #include "MessageIdentifiers.h"
- #include "RakPeerInterface.h"
- #include "MTUSize.h"
- #include "GetTime.h"
- #include "PacketLogger.h"
- using namespace RakNet;
- void NatPunchthroughServerDebugInterface_Printf::OnServerMessage(const char *msg)
- {
- printf("%s\n", msg);
- }
- #if _RAKNET_SUPPORT_PacketLogger==1
- void NatPunchthroughServerDebugInterface_PacketLogger::OnServerMessage(const char *msg)
- {
- if (pl)
- {
- pl->WriteMiscellaneous("Nat", msg);
- }
- }
- #endif
- void NatPunchthroughServer::User::DeleteConnectionAttempt(NatPunchthroughServer::ConnectionAttempt *ca)
- {
- unsigned int index = connectionAttempts.GetIndexOf(ca);
- if ((unsigned int)index!=(unsigned int)-1)
- {
- RakNet::OP_DELETE(ca,_FILE_AND_LINE_);
- connectionAttempts.RemoveAtIndex(index);
- }
- }
- void NatPunchthroughServer::User::DerefConnectionAttempt(NatPunchthroughServer::ConnectionAttempt *ca)
- {
- unsigned int index = connectionAttempts.GetIndexOf(ca);
- if ((unsigned int)index!=(unsigned int)-1)
- {
- connectionAttempts.RemoveAtIndex(index);
- }
- }
- bool NatPunchthroughServer::User::HasConnectionAttemptToUser(User *user)
- {
- unsigned int index;
- for (index=0; index < connectionAttempts.Size(); index++)
- {
- if (connectionAttempts[index]->recipient->guid==user->guid ||
- connectionAttempts[index]->sender->guid==user->guid)
- return true;
- }
- return false;
- }
- void NatPunchthroughServer::User::LogConnectionAttempts(RakNet::RakString &rs)
- {
- rs.Clear();
- unsigned int index;
- char guidStr[128], ipStr[128];
- guid.ToString(guidStr);
- systemAddress.ToString(true,ipStr);
- rs=RakNet::RakString("User systemAddress=%s guid=%s\n", ipStr, guidStr);
- rs+=RakNet::RakString("%i attempts in list:\n", connectionAttempts.Size());
- for (index=0; index < connectionAttempts.Size(); index++)
- {
- rs+=RakNet::RakString("%i. SessionID=%i ", index+1, connectionAttempts[index]->sessionId);
- if (connectionAttempts[index]->sender==this)
- rs+="(We are sender) ";
- else
- rs+="(We are recipient) ";
- if (isReady)
- rs+="(READY TO START) ";
- else
- rs+="(NOT READY TO START) ";
- if (connectionAttempts[index]->attemptPhase==NatPunchthroughServer::ConnectionAttempt::NAT_ATTEMPT_PHASE_NOT_STARTED)
- rs+="(NOT_STARTED). ";
- else
- rs+="(GETTING_RECENT_PORTS). ";
- if (connectionAttempts[index]->sender==this)
- {
- connectionAttempts[index]->recipient->guid.ToString(guidStr);
- connectionAttempts[index]->recipient->systemAddress.ToString(true,ipStr);
- }
- else
- {
- connectionAttempts[index]->sender->guid.ToString(guidStr);
- connectionAttempts[index]->sender->systemAddress.ToString(true,ipStr);
- }
- rs+=RakNet::RakString("Target systemAddress=%s, guid=%s.\n", ipStr, guidStr);
- }
- }
- int RakNet::NatPunchthroughServer::NatPunchthroughUserComp( const RakNetGUID &key, User * const &data )
- {
- if (key < data->guid)
- return -1;
- if (key > data->guid)
- return 1;
- return 0;
- }
- STATIC_FACTORY_DEFINITIONS(NatPunchthroughServer,NatPunchthroughServer);
- NatPunchthroughServer::NatPunchthroughServer()
- {
- lastUpdate=0;
- sessionId=0;
- natPunchthroughServerDebugInterface=0;
- for (int i=0; i < MAXIMUM_NUMBER_OF_INTERNAL_IDS; i++)
- boundAddresses[i]=UNASSIGNED_SYSTEM_ADDRESS;
- boundAddressCount=0;
- }
- NatPunchthroughServer::~NatPunchthroughServer()
- {
- User *user, *otherUser;
- ConnectionAttempt *connectionAttempt;
- unsigned int j;
- while(users.Size())
- {
- user = users[0];
- for (j=0; j < user->connectionAttempts.Size(); j++)
- {
- connectionAttempt=user->connectionAttempts[j];
- if (connectionAttempt->sender==user)
- otherUser=connectionAttempt->recipient;
- else
- otherUser=connectionAttempt->sender;
- otherUser->DeleteConnectionAttempt(connectionAttempt);
- }
- RakNet::OP_DELETE(user,_FILE_AND_LINE_);
- users[0]=users[users.Size()-1];
- users.RemoveAtIndex(users.Size()-1);
- }
- }
- void NatPunchthroughServer::SetDebugInterface(NatPunchthroughServerDebugInterface *i)
- {
- natPunchthroughServerDebugInterface=i;
- }
- void NatPunchthroughServer::Update(void)
- {
- ConnectionAttempt *connectionAttempt;
- User *user, *recipient;
- unsigned int i,j;
- RakNet::Time time = RakNet::GetTime();
- if (time > lastUpdate+250)
- {
- lastUpdate=time;
- for (i=0; i < users.Size(); i++)
- {
- user=users[i];
- for (j=0; j < user->connectionAttempts.Size(); j++)
- {
- connectionAttempt=user->connectionAttempts[j];
- if (connectionAttempt->sender==user)
- {
- if (connectionAttempt->attemptPhase!=ConnectionAttempt::NAT_ATTEMPT_PHASE_NOT_STARTED &&
- time > connectionAttempt->startTime &&
- time > 10000 + connectionAttempt->startTime ) // Formerly 5000, but sometimes false positives
- {
- RakNet::BitStream outgoingBs;
-
- // that other system might not be running the plugin
- outgoingBs.Write((MessageID)ID_NAT_TARGET_UNRESPONSIVE);
- outgoingBs.Write(connectionAttempt->recipient->guid);
- outgoingBs.Write(connectionAttempt->sessionId);
- rakPeerInterface->Send(&outgoingBs,HIGH_PRIORITY,RELIABLE_ORDERED,0,connectionAttempt->sender->systemAddress,false);
- // 05/28/09 Previously only told sender about ID_NAT_CONNECTION_TO_TARGET_LOST
- // However, recipient may be expecting it due to external code
- // In that case, recipient would never get any response if the sender dropped
- outgoingBs.Reset();
- outgoingBs.Write((MessageID)ID_NAT_TARGET_UNRESPONSIVE);
- outgoingBs.Write(connectionAttempt->sender->guid);
- outgoingBs.Write(connectionAttempt->sessionId);
- rakPeerInterface->Send(&outgoingBs,HIGH_PRIORITY,RELIABLE_ORDERED,0,connectionAttempt->recipient->systemAddress,false);
- connectionAttempt->sender->isReady=true;
- connectionAttempt->recipient->isReady=true;
- recipient=connectionAttempt->recipient;
- if (natPunchthroughServerDebugInterface)
- {
- char str[1024];
- char addr1[128], addr2[128];
- // 8/01/09 Fixed bug where this was after DeleteConnectionAttempt()
- connectionAttempt->sender->systemAddress.ToString(true,addr1);
- connectionAttempt->recipient->systemAddress.ToString(true,addr2);
- sprintf(str, "Sending ID_NAT_TARGET_UNRESPONSIVE to sender %s and recipient %s.", addr1, addr2);
- natPunchthroughServerDebugInterface->OnServerMessage(str);
- RakNet::RakString log;
- connectionAttempt->sender->LogConnectionAttempts(log);
- connectionAttempt->recipient->LogConnectionAttempts(log);
- }
- connectionAttempt->sender->DerefConnectionAttempt(connectionAttempt);
- connectionAttempt->recipient->DeleteConnectionAttempt(connectionAttempt);
- StartPunchthroughForUser(user);
- StartPunchthroughForUser(recipient);
- break;
- }
- }
- }
- }
- }
- }
- PluginReceiveResult NatPunchthroughServer::OnReceive(Packet *packet)
- {
- switch (packet->data[0])
- {
- case ID_NAT_PUNCHTHROUGH_REQUEST:
- OnNATPunchthroughRequest(packet);
- return RR_STOP_PROCESSING_AND_DEALLOCATE;
- case ID_NAT_GET_MOST_RECENT_PORT:
- OnGetMostRecentPort(packet);
- return RR_STOP_PROCESSING_AND_DEALLOCATE;
- case ID_NAT_CLIENT_READY:
- OnClientReady(packet);
- return RR_STOP_PROCESSING_AND_DEALLOCATE;
- case ID_NAT_REQUEST_BOUND_ADDRESSES:
- {
- RakNet::BitStream outgoingBs;
- outgoingBs.Write((MessageID)ID_NAT_RESPOND_BOUND_ADDRESSES);
-
- if (boundAddresses[0]==UNASSIGNED_SYSTEM_ADDRESS)
- {
- DataStructures::List<RakNetSocket2* > sockets;
- rakPeerInterface->GetSockets(sockets);
- for (int i=0; i < sockets.Size() && i < MAXIMUM_NUMBER_OF_INTERNAL_IDS; i++)
- {
- boundAddresses[i]=sockets[i]->GetBoundAddress();
- boundAddressCount++;
- }
- }
- outgoingBs.Write(boundAddressCount);
- for (int i=0; i < boundAddressCount; i++)
- {
- outgoingBs.Write(boundAddresses[i]);
- }
- rakPeerInterface->Send(&outgoingBs,HIGH_PRIORITY,RELIABLE_ORDERED,0,packet->systemAddress,false);
- }
- return RR_STOP_PROCESSING_AND_DEALLOCATE;
- case ID_NAT_PING:
- {
- }
- return RR_STOP_PROCESSING_AND_DEALLOCATE;
- case ID_OUT_OF_BAND_INTERNAL:
- if (packet->length>=2 && packet->data[1]==ID_NAT_PING)
- {
- RakNet::BitStream bs(packet->data,packet->length,false);
- bs.IgnoreBytes(sizeof(MessageID)*2);
- uint16_t externalPort;
- bs.Read(externalPort);
- RakNet::BitStream outgoingBs;
- outgoingBs.Write((MessageID)ID_NAT_PONG);
- outgoingBs.Write(externalPort);
- uint16_t externalPort2 = packet->systemAddress.GetPort();
- outgoingBs.Write(externalPort2);
- rakPeerInterface->SendOutOfBand((const char*) packet->systemAddress.ToString(false),packet->systemAddress.GetPort(),(const char*) outgoingBs.GetData(),outgoingBs.GetNumberOfBytesUsed());
- return RR_STOP_PROCESSING_AND_DEALLOCATE;
- }
- }
- return RR_CONTINUE_PROCESSING;
- }
- void NatPunchthroughServer::OnClosedConnection(const SystemAddress &systemAddress, RakNetGUID rakNetGUID, PI2_LostConnectionReason lostConnectionReason )
- {
- (void) lostConnectionReason;
- (void) systemAddress;
- unsigned int i=0;
- bool objectExists;
- i = users.GetIndexFromKey(rakNetGUID, &objectExists);
- if (objectExists)
- {
- RakNet::BitStream outgoingBs;
- DataStructures::List<User *> freedUpInProgressUsers;
- User *user = users[i];
- User *otherUser;
- unsigned int connectionAttemptIndex;
- ConnectionAttempt *connectionAttempt;
- for (connectionAttemptIndex=0; connectionAttemptIndex < user->connectionAttempts.Size(); connectionAttemptIndex++)
- {
- connectionAttempt=user->connectionAttempts[connectionAttemptIndex];
- outgoingBs.Reset();
- if (connectionAttempt->recipient==user)
- {
- otherUser=connectionAttempt->sender;
- }
- else
- {
- otherUser=connectionAttempt->recipient;
- }
- // 05/28/09 Previously only told sender about ID_NAT_CONNECTION_TO_TARGET_LOST
- // However, recipient may be expecting it due to external code
- // In that case, recipient would never get any response if the sender dropped
- outgoingBs.Write((MessageID)ID_NAT_CONNECTION_TO_TARGET_LOST);
- outgoingBs.Write(rakNetGUID);
- outgoingBs.Write(connectionAttempt->sessionId);
- rakPeerInterface->Send(&outgoingBs,HIGH_PRIORITY,RELIABLE_ORDERED,0,otherUser->systemAddress,false);
- // 4/22/09 - Bug: was checking inProgress, legacy variable not used elsewhere
- if (connectionAttempt->attemptPhase==ConnectionAttempt::NAT_ATTEMPT_PHASE_GETTING_RECENT_PORTS)
- {
- otherUser->isReady=true;
- freedUpInProgressUsers.Insert(otherUser, _FILE_AND_LINE_ );
- }
- otherUser->DeleteConnectionAttempt(connectionAttempt);
- }
- RakNet::OP_DELETE(users[i], _FILE_AND_LINE_);
- users.RemoveAtIndex(i);
- for (i=0; i < freedUpInProgressUsers.Size(); i++)
- {
- StartPunchthroughForUser(freedUpInProgressUsers[i]);
- }
- }
- /*
- // Also remove from groupPunchthroughRequests
- for (i=0; i < users.Size(); i++)
- {
- bool objectExists;
- unsigned int gprIndex;
- gprIndex = users[i]->groupPunchthroughRequests.GetIndexFromKey(rakNetGUID, &objectExists);
- if (objectExists)
- {
- // printf("DEBUG %i\n", __LINE__);
- RakNet::BitStream outgoingBs;
- outgoingBs.Write((MessageID)ID_NAT_TARGET_NOT_CONNECTED);
- outgoingBs.Write(rakNetGUID);
- rakPeerInterface->Send(&outgoingBs,HIGH_PRIORITY,RELIABLE_ORDERED,0,users[i]->systemAddress,false);
- users[i]->groupPunchthroughRequests.RemoveAtIndex(gprIndex);
- }
- }
- */
- }
- void NatPunchthroughServer::OnNewConnection(const SystemAddress &systemAddress, RakNetGUID rakNetGUID, bool isIncoming)
- {
- (void) systemAddress;
- (void) isIncoming;
- User *user = RakNet::OP_NEW<User>(_FILE_AND_LINE_);
- user->guid=rakNetGUID;
- user->mostRecentPort=0;
- user->systemAddress=systemAddress;
- user->isReady=true;
- users.Insert(rakNetGUID, user, true, _FILE_AND_LINE_);
- // printf("Adding to users %s\n", rakNetGUID.ToString());
- // printf("DEBUG users[0] guid=%s\n", users[0]->guid.ToString());
- }
- void NatPunchthroughServer::OnNATPunchthroughRequest(Packet *packet)
- {
- RakNet::BitStream outgoingBs;
- RakNet::BitStream incomingBs(packet->data, packet->length, false);
- incomingBs.IgnoreBytes(sizeof(MessageID));
- RakNetGUID recipientGuid, senderGuid;
- incomingBs.Read(recipientGuid);
- senderGuid=packet->guid;
- unsigned int i;
- bool objectExists;
- i = users.GetIndexFromKey(senderGuid, &objectExists);
- RakAssert(objectExists);
- ConnectionAttempt *ca = RakNet::OP_NEW<ConnectionAttempt>(_FILE_AND_LINE_);
- ca->sender=users[i];
- ca->sessionId=sessionId++;
- i = users.GetIndexFromKey(recipientGuid, &objectExists);
- if (objectExists==false || ca->sender == ca->recipient)
- {
- // printf("DEBUG %i\n", __LINE__);
- // printf("DEBUG recipientGuid=%s\n", recipientGuid.ToString());
- // printf("DEBUG users[0] guid=%s\n", users[0]->guid.ToString());
- outgoingBs.Write((MessageID)ID_NAT_TARGET_NOT_CONNECTED);
- outgoingBs.Write(recipientGuid);
- rakPeerInterface->Send(&outgoingBs,HIGH_PRIORITY,RELIABLE_ORDERED,0,packet->systemAddress,false);
- RakNet::OP_DELETE(ca,_FILE_AND_LINE_);
- return;
- }
- ca->recipient=users[i];
- if (ca->recipient->HasConnectionAttemptToUser(ca->sender))
- {
- outgoingBs.Write((MessageID)ID_NAT_ALREADY_IN_PROGRESS);
- outgoingBs.Write(recipientGuid);
- rakPeerInterface->Send(&outgoingBs,HIGH_PRIORITY,RELIABLE_ORDERED,0,packet->systemAddress,false);
- RakNet::OP_DELETE(ca,_FILE_AND_LINE_);
- return;
- }
- ca->sender->connectionAttempts.Insert(ca, _FILE_AND_LINE_ );
- ca->recipient->connectionAttempts.Insert(ca, _FILE_AND_LINE_ );
- StartPunchthroughForUser(ca->sender);
- }
- void NatPunchthroughServer::OnClientReady(Packet *packet)
- {
- unsigned int i;
- bool objectExists;
- i = users.GetIndexFromKey(packet->guid, &objectExists);
- if (objectExists)
- {
- users[i]->isReady=true;
- StartPunchthroughForUser(users[i]);
- }
- }
- void NatPunchthroughServer::OnGetMostRecentPort(Packet *packet)
- {
- RakNet::BitStream bsIn(packet->data, packet->length, false);
- bsIn.IgnoreBytes(sizeof(MessageID));
- uint16_t sessionId;
- unsigned short mostRecentPort;
- bsIn.Read(sessionId);
- bsIn.Read(mostRecentPort);
- unsigned int i,j;
- User *user;
- ConnectionAttempt *connectionAttempt;
- bool objectExists;
- i = users.GetIndexFromKey(packet->guid, &objectExists);
- if (natPunchthroughServerDebugInterface)
- {
- RakNet::RakString log;
- char addr1[128], addr2[128];
- packet->systemAddress.ToString(true,addr1);
- packet->guid.ToString(addr2);
- log=RakNet::RakString("Got ID_NAT_GET_MOST_RECENT_PORT from systemAddress %s guid %s. port=%i. sessionId=%i. userFound=%i.", addr1, addr2, mostRecentPort, sessionId, objectExists);
- natPunchthroughServerDebugInterface->OnServerMessage(log.C_String());
- }
- if (objectExists)
- {
- user=users[i];
- user->mostRecentPort=mostRecentPort;
- RakNet::Time time = RakNet::GetTime();
- for (j=0; j < user->connectionAttempts.Size(); j++)
- {
- connectionAttempt=user->connectionAttempts[j];
- if (connectionAttempt->attemptPhase==ConnectionAttempt::NAT_ATTEMPT_PHASE_GETTING_RECENT_PORTS &&
- connectionAttempt->sender->mostRecentPort!=0 &&
- connectionAttempt->recipient->mostRecentPort!=0 &&
- // 04/29/08 add sessionId to prevent processing for other systems
- connectionAttempt->sessionId==sessionId)
- {
- SystemAddress senderSystemAddress = connectionAttempt->sender->systemAddress;
- SystemAddress recipientSystemAddress = connectionAttempt->recipient->systemAddress;
- SystemAddress recipientTargetAddress = recipientSystemAddress;
- SystemAddress senderTargetAddress = senderSystemAddress;
- recipientTargetAddress.SetPortHostOrder(connectionAttempt->recipient->mostRecentPort);
- senderTargetAddress.SetPortHostOrder(connectionAttempt->sender->mostRecentPort);
- // Pick a time far enough in the future that both systems will have gotten the message
- int targetPing = rakPeerInterface->GetAveragePing(recipientTargetAddress);
- int senderPing = rakPeerInterface->GetAveragePing(senderSystemAddress);
- RakNet::Time simultaneousAttemptTime;
- if (targetPing==-1 || senderPing==-1)
- simultaneousAttemptTime = time + 1500;
- else
- {
- int largerPing = targetPing > senderPing ? targetPing : senderPing;
- if (largerPing * 4 < 100)
- simultaneousAttemptTime = time + 100;
- else
- simultaneousAttemptTime = time + (largerPing * 4);
- }
- if (natPunchthroughServerDebugInterface)
- {
- RakNet::RakString log;
- char addr1[128], addr2[128];
- recipientSystemAddress.ToString(true,addr1);
- connectionAttempt->recipient->guid.ToString(addr2);
- log=RakNet::RakString("Sending ID_NAT_CONNECT_AT_TIME to recipient systemAddress %s guid %s", addr1, addr2);
- natPunchthroughServerDebugInterface->OnServerMessage(log.C_String());
- }
- // Send to recipient timestamped message to connect at time
- RakNet::BitStream bsOut;
- bsOut.Write((MessageID)ID_TIMESTAMP);
- bsOut.Write(simultaneousAttemptTime);
- bsOut.Write((MessageID)ID_NAT_CONNECT_AT_TIME);
- bsOut.Write(connectionAttempt->sessionId);
- bsOut.Write(senderTargetAddress); // Public IP, using most recent port
- for (j=0; j < MAXIMUM_NUMBER_OF_INTERNAL_IDS; j++) // Internal IP
- bsOut.Write(rakPeerInterface->GetInternalID(senderSystemAddress,j));
- bsOut.Write(connectionAttempt->sender->guid);
- bsOut.Write(false);
- rakPeerInterface->Send(&bsOut,HIGH_PRIORITY,RELIABLE_ORDERED,0,recipientSystemAddress,false);
- if (natPunchthroughServerDebugInterface)
- {
- RakNet::RakString log;
- char addr1[128], addr2[128];
- senderSystemAddress.ToString(true,addr1);
- connectionAttempt->sender->guid.ToString(addr2);
- log=RakNet::RakString("Sending ID_NAT_CONNECT_AT_TIME to sender systemAddress %s guid %s", addr1, addr2);
- natPunchthroughServerDebugInterface->OnServerMessage(log.C_String());
- }
- // Same for sender
- bsOut.Reset();
- bsOut.Write((MessageID)ID_TIMESTAMP);
- bsOut.Write(simultaneousAttemptTime);
- bsOut.Write((MessageID)ID_NAT_CONNECT_AT_TIME);
- bsOut.Write(connectionAttempt->sessionId);
- bsOut.Write(recipientTargetAddress); // Public IP, using most recent port
- for (j=0; j < MAXIMUM_NUMBER_OF_INTERNAL_IDS; j++) // Internal IP
- bsOut.Write(rakPeerInterface->GetInternalID(recipientSystemAddress,j));
- bsOut.Write(connectionAttempt->recipient->guid);
- bsOut.Write(true);
- rakPeerInterface->Send(&bsOut,HIGH_PRIORITY,RELIABLE_ORDERED,0,senderSystemAddress,false);
- connectionAttempt->recipient->DerefConnectionAttempt(connectionAttempt);
- connectionAttempt->sender->DeleteConnectionAttempt(connectionAttempt);
- // 04/29/08 missing return
- return;
- }
- }
- }
- else
- {
- if (natPunchthroughServerDebugInterface)
- {
- RakNet::RakString log;
- char addr1[128], addr2[128];
- packet->systemAddress.ToString(true,addr1);
- packet->guid.ToString(addr2);
- log=RakNet::RakString("Ignoring ID_NAT_GET_MOST_RECENT_PORT from systemAddress %s guid %s", addr1, addr2);
- natPunchthroughServerDebugInterface->OnServerMessage(log.C_String());
- }
- }
- }
- void NatPunchthroughServer::StartPunchthroughForUser(User *user)
- {
- if (user->isReady==false)
- return;
- ConnectionAttempt *connectionAttempt;
- User *sender,*recipient,*otherUser;
- unsigned int i;
- for (i=0; i < user->connectionAttempts.Size(); i++)
- {
- connectionAttempt=user->connectionAttempts[i];
- if (connectionAttempt->sender==user)
- {
- otherUser=connectionAttempt->recipient;
- sender=user;
- recipient=otherUser;
- }
- else
- {
- otherUser=connectionAttempt->sender;
- recipient=user;
- sender=otherUser;
- }
- if (otherUser->isReady)
- {
- if (natPunchthroughServerDebugInterface)
- {
- char str[1024];
- char addr1[128], addr2[128];
- sender->systemAddress.ToString(true,addr1);
- recipient->systemAddress.ToString(true,addr2);
- sprintf(str, "Sending NAT_ATTEMPT_PHASE_GETTING_RECENT_PORTS to sender %s and recipient %s.", addr1, addr2);
- natPunchthroughServerDebugInterface->OnServerMessage(str);
- }
- sender->isReady=false;
- recipient->isReady=false;
- connectionAttempt->attemptPhase=ConnectionAttempt::NAT_ATTEMPT_PHASE_GETTING_RECENT_PORTS;
- connectionAttempt->startTime=RakNet::GetTime();
- sender->mostRecentPort=0;
- recipient->mostRecentPort=0;
- RakNet::BitStream outgoingBs;
- outgoingBs.Write((MessageID)ID_NAT_GET_MOST_RECENT_PORT);
- // 4/29/09 Write sessionID so we don't use returned port for a system we don't want
- outgoingBs.Write(connectionAttempt->sessionId);
- rakPeerInterface->Send(&outgoingBs,HIGH_PRIORITY,RELIABLE_ORDERED,0,sender->systemAddress,false);
- rakPeerInterface->Send(&outgoingBs,HIGH_PRIORITY,RELIABLE_ORDERED,0,recipient->systemAddress,false);
- // 4/22/09 - BUG: missing break statement here
- break;
- }
- }
- }
- #endif // _RAKNET_SUPPORT_*
|