예제 #1
0
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);
		*/

}
예제 #2
0
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();
	}
}
예제 #3
0
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);
		}		
	}
}
예제 #5
0
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;
}
예제 #6
0
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;
}
예제 #7
0
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);
}