void NatPunchthrough::ConnectionRequest::GetAddressList(RakPeerInterface *rakPeer, DataStructures::List<SystemAddress> &fallbackAddresses, SystemAddress publicAddress, SystemAddress privateAddress, bool excludeConnected) { SystemAddress fallback; fallbackAddresses.Clear(true); fallback.binaryAddress=publicAddress.binaryAddress; fallback.port=publicAddress.port; if (excludeConnected==false || rakPeer->IsConnected(fallback,true)==false) fallbackAddresses.Insert(fallback); if (privateAddress!=publicAddress && privateAddress!=UNASSIGNED_SYSTEM_ADDRESS && (excludeConnected==false ||rakPeer->IsConnected(privateAddress,true)==false)) fallbackAddresses.Insert(privateAddress); fallback.port=publicAddress.port+1; if (excludeConnected==false || rakPeer->IsConnected(fallback,true)==false) fallbackAddresses.Insert(fallback); fallback.port=publicAddress.port+2; if (excludeConnected==false || rakPeer->IsConnected(fallback,true)==false) fallbackAddresses.Insert(fallback); fallback.port=rakPeer->GetInternalID().port; if (fallbackAddresses.GetIndexOf(fallback)==(unsigned) -1 && (excludeConnected==false || rakPeer->IsConnected(fallback,true)==false)) fallbackAddresses.Insert(fallback); fallback.port=rakPeer->GetInternalID().port+1; if (fallbackAddresses.GetIndexOf(fallback)==(unsigned) -1 && (excludeConnected==false || rakPeer->IsConnected(fallback,true)==false)) fallbackAddresses.Insert(fallback); fallback.port=rakPeer->GetInternalID().port+2; if (fallbackAddresses.GetIndexOf(fallback)==(unsigned) -1 && (excludeConnected==false || rakPeer->IsConnected(fallback,true)==false)) fallbackAddresses.Insert(fallback); // Try to keep down the number of fallbacks or the router may run out of mappings /* fallback.port=publicAddress.port+3; if (excludeConnected==false || rakPeer->IsConnected(fallback,true)==false) fallbackAddresses.Insert(fallback); fallback.port=publicAddress.port+4; if (excludeConnected==false || rakPeer->IsConnected(fallback,true)==false) fallbackAddresses.Insert(fallback); fallback.port=rakPeer->GetInternalID().port+3; if (fallbackAddresses.GetIndexOf(fallback)==(unsigned) -1 && (excludeConnected==false || rakPeer->IsConnected(fallback,true)==false)) fallbackAddresses.Insert(fallback); fallback.port=rakPeer->GetInternalID().port+4; if (fallbackAddresses.GetIndexOf(fallback)==(unsigned) -1 && (excludeConnected==false || rakPeer->IsConnected(fallback,true)==false)) fallbackAddresses.Insert(fallback); */ }
void SQLiteServerLoggerPlugin::CloseUnreferencedSessions(void) { DataStructures::List<sqlite3 *> sessionNames; unsigned int j; for (j=0; j < loggedInSessions.Size(); j++) { if (sessionNames.GetIndexOf(loggedInSessions[j].referencedPointer)==-1) sessionNames.Push(loggedInSessions[j].referencedPointer, _FILE_AND_LINE_ ); } DataStructures::List<sqlite3*> unreferencedHandles; bool isReferenced; for (unsigned int i=0; i < dbHandles.GetSize(); i++) { if (dbHandles[i].dbAutoCreated) { j=0; isReferenced=false; for (j=0; j < sessionNames.Size(); j++) { if (sessionNames[j]==dbHandles[i].dbHandle) { isReferenced=true; break; } } if (isReferenced==false) { unreferencedHandles.Push(dbHandles[i].dbHandle,_FILE_AND_LINE_); } } } if (unreferencedHandles.Size()) { sqlLoggerThreadPool.LockInput(); if (sqlLoggerThreadPool.HasInputFast()==false) { RakSleep(100); while (sqlLoggerThreadPool.NumThreadsWorking()>0) RakSleep(30); for (unsigned int k=0; k < unreferencedHandles.Size(); k++) { RemoveDBHandle(unreferencedHandles[k], true); } } sqlLoggerThreadPool.UnlockInput(); if (dbHandles.GetSize()==0) StopCPUSQLThreads(); } }
void TableSerializer::SerializeRow(DataStructures::Table::Row *in, unsigned keyIn, DataStructures::List<DataStructures::Table::ColumnDescriptor> &columns, RakNet::BitStream *out, DataStructures::List<int> &skipColumnIndices) { unsigned cellIndex; out->Write(keyIn); for (cellIndex=0; cellIndex<columns.Size(); cellIndex++) { if (skipColumnIndices.GetIndexOf(cellIndex)==(unsigned)-1) { SerializeCell(out, in->cells[cellIndex], columns[cellIndex].columnType); } } }
void TableSerializer::SerializeColumns(DataStructures::Table *in, RakNet::BitStream *out, DataStructures::List<int> &skipColumnIndices) { const DataStructures::List<DataStructures::Table::ColumnDescriptor> &columns=in->GetColumns(); out->Write((unsigned)columns.Size()-skipColumnIndices.Size()); unsigned i; for (i=0; i<columns.Size(); i++) { if (skipColumnIndices.GetIndexOf(i)==(unsigned)-1) { StringCompressor::Instance()->EncodeString(columns[i].columnName, _TABLE_MAX_COLUMN_NAME_LENGTH, out); out->Write((unsigned char)columns[i].columnType); } } }
PluginReceiveResult NatPunchthrough::OnNewIncomingConnection(Packet *packet) { unsigned i; i=0; while (i < connectionRequestList.Size()) { DataStructures::List<SystemAddress> fallbackAddresses; connectionRequestList[i]->GetAddressList(rakPeer, fallbackAddresses, connectionRequestList[i]->senderPublic, connectionRequestList[i]->senderPrivate, false); if (fallbackAddresses.GetIndexOf(packet->systemAddress)!=(unsigned) -1) { rakFree(connectionRequestList[i]->passwordData); delete connectionRequestList[i]; connectionRequestList.RemoveAtIndex(i); return RR_CONTINUE_PROCESSING; } i++; } // return to user return RR_CONTINUE_PROCESSING; }
PluginReceiveResult NatPunchthrough::OnConnectionAttemptFailed(Packet *packet) { // SystemAddress publicOne, publicTwo; // SystemAddress privateZero, privateOne, privateTwo; // SystemAddress receiverAddrWithFPort; // SystemAddress receiverAddrWithSPort; // SystemAddress receiverAddrWithIPort; DataStructures::List<SystemAddress> fallbackAddresses; unsigned i,addressIndex; i=0; while (i < connectionRequestList.Size()) { // Advertised port has priority. If set, use that. If fails on that, fail totally. if (connectionRequestList[i]->advertisedPort!=0) { SystemAddress advertisedAddress; advertisedAddress.binaryAddress=connectionRequestList[i]->receiverPublic.binaryAddress; advertisedAddress.port=connectionRequestList[i]->advertisedPort; if (packet->systemAddress==advertisedAddress) { // Couldn't connect to the advertised port, meaning uni-directional communication. Total failure. // Shouldn't really ever hit this. LogOut(FormatString("Failed to connect to remotely transmitted port from %s.\nCommunication would only be unidirectional.\n", packet->systemAddress.ToString(true))); rakFree(connectionRequestList[i]->passwordData); delete connectionRequestList[i]; packet->systemAddress=connectionRequestList[i]->receiverPublic; connectionRequestList.RemoveAtIndex(i); return RR_CONTINUE_PROCESSING; } else { LogOut(FormatString("Connecting to remotely advertised address %s\n", advertisedAddress.ToString(true))); rakPeer->Connect(advertisedAddress.ToString(false), advertisedAddress.port, connectionRequestList[i]->passwordData, connectionRequestList[i]->passwordDataLength); return RR_STOP_PROCESSING_AND_DEALLOCATE; } } connectionRequestList[i]->GetAddressList(rakPeer, fallbackAddresses, connectionRequestList[i]->receiverPublic, connectionRequestList[i]->receiverPrivate, false); addressIndex=fallbackAddresses.GetIndexOf(packet->systemAddress); if (addressIndex != (unsigned) -1) { if (addressIndex<fallbackAddresses.Size()-1) { LogOut(FormatString("Connecting to fallback address %s\n", fallbackAddresses[addressIndex+1].ToString(true))); rakPeer->Connect(fallbackAddresses[addressIndex+1].ToString(false), fallbackAddresses[addressIndex+1].port, connectionRequestList[i]->passwordData, connectionRequestList[i]->passwordDataLength); return RR_STOP_PROCESSING_AND_DEALLOCATE; } else { LogOut(FormatString("NAT punchthrough failed.")); LogOut(FormatString("Last attempted address=%s\n", packet->systemAddress.ToString())); LogOut(FormatString("Address list:\n")); unsigned j; for (j=0; j < fallbackAddresses.Size(); j++) LogOut(FormatString("%i. %s\n", j+1, fallbackAddresses[j].ToString())); // Totally failed rakFree(connectionRequestList[i]->passwordData); delete connectionRequestList[i]; // Both attempts failed, return the notification packet->systemAddress=connectionRequestList[i]->receiverPublic; connectionRequestList.RemoveAtIndex(i); return RR_CONTINUE_PROCESSING; } } i++; } // Unrelated, return notification return RR_CONTINUE_PROCESSING; }
void MasterServer::HandleQuery(Packet *packet) { DataStructures::List<GameServer*> serversWithKeysList; char ruleIdentifier[256]; unsigned index, serverIndex; int key; bool queryAll; BitStream outputBitStream; BitStream compressedString(packet->data, packet->length, false); compressedString.IgnoreBits(8*sizeof(unsigned char)); queryAll=true; while (compressedString.GetNumberOfUnreadBits()>0) { // Generate a list of the indices of the servers that have one or more of the specified keys. stringCompressor->DecodeString(ruleIdentifier, 256, &compressedString); if (ruleIdentifier[0]==0) // If we fail to read the first string, queryAll remains true. break; queryAll=false; if (IsReservedRuleIdentifier(ruleIdentifier)) continue; for (index=0; index < gameServerList.serverList.Size(); index++) { if (gameServerList.serverList[index]->connectionIdentifier==UNASSIGNED_PLAYER_ID) continue; if (gameServerList.serverList[index]->FindKey(ruleIdentifier)) { serverIndex=serversWithKeysList.GetIndexOf(gameServerList.serverList[index]); if (serverIndex==MAX_UNSIGNED_LONG) { gameServerList.serverList[index]->numberOfKeysFound=1; serversWithKeysList.Insert(gameServerList.serverList[index]); } else { serversWithKeysList[serverIndex]->numberOfKeysFound++; } } } } // Write the packet id if (queryAll) outputBitStream.Write((unsigned char) ID_MASTER_SERVER_SET_SERVER); else outputBitStream.Write((unsigned char) ID_MASTER_SERVER_UPDATE_SERVER); if (queryAll) { // Write the number of servers outputBitStream.WriteCompressed((unsigned short)gameServerList.serverList.Size()); for (index=0; index < gameServerList.serverList.Size(); index++) { // Write the whole server SerializeServer(gameServerList.serverList[index], &outputBitStream); } } else { compressedString.ResetReadPointer(); compressedString.IgnoreBits(8*sizeof(unsigned char)); // Write the number of servers with requested keys outputBitStream.WriteCompressed((unsigned short)serversWithKeysList.Size()); // For each server, write the header which consists of the IP/PORT. // Then go through the list of requested keys and write those for (index=0; index < serversWithKeysList.Size(); index++) { SerializePlayerID(&(serversWithKeysList[index]->connectionIdentifier), &outputBitStream); outputBitStream.WriteCompressed((unsigned short)serversWithKeysList[index]->numberOfKeysFound); while (compressedString.GetNumberOfUnreadBits()>0) { // Generate a list of the indices of the servers that have one or more of the specified keys. stringCompressor->DecodeString(ruleIdentifier, 256, &compressedString); if (ruleIdentifier[0]==0) break; if (IsReservedRuleIdentifier(ruleIdentifier)) continue; serversWithKeysList[index]->FindKey(ruleIdentifier); key=serversWithKeysList[index]->keyIndex; if (key>=0) SerializeRule(serversWithKeysList[index]->serverRules[key], &outputBitStream); } } } rakPeer->Send(&outputBitStream, MEDIUM_PRIORITY, RELIABLE, 0, packet->playerId, false); }