ACTIONSCRIPT_CALLABLE_FUNCTION(RoomsBrowserGFx3_RakNet, f2c_JoinByFilter)
{
	if (pparams.GetArgCount()<1)
		return;

	RakNet::JoinByFilter_Func func;
	func.userName=loginUsername;
	func.gameIdentifier=titleName;
	func.roomMemberMode=RMM_ANY_PLAYABLE;

	bool roomIsFromServer=pparams[0].GetBool();
	double roomGuid=pparams[1].GetNumber();

	if (roomIsFromServer)
	{
		// See RoomTypes.h for other default columns
		func.query.AddQuery_NUMERIC( DefaultRoomColumns::GetColumnName(DefaultRoomColumns::TC_ROOM_ID), roomGuid);
		roomsPlugin->ExecuteFunc(&func);
	}
	else
	{
		SystemAddress sa;
		sa.FromString(pparams[2].GetString());
		char ipPart[32];
		sa.ToString(false,ipPart);
		rakPeer->Connect(ipPart,sa.GetPort(),0,0);
	}

}
SystemAddress TCPInterface::Connect(const char* host, unsigned short remotePort, bool block, unsigned short socketFamily, const char *bindAddress)
{
	if (threadRunning.GetValue()==0)
		return UNASSIGNED_SYSTEM_ADDRESS;

	int newRemoteClientIndex=-1;
	for (newRemoteClientIndex=0; newRemoteClientIndex < remoteClientsLength; newRemoteClientIndex++)
	{
		remoteClients[newRemoteClientIndex].isActiveMutex.Lock();
		if (remoteClients[newRemoteClientIndex].isActive==false)
		{
			remoteClients[newRemoteClientIndex].SetActive(true);
			remoteClients[newRemoteClientIndex].isActiveMutex.Unlock();
			break;
		}
		remoteClients[newRemoteClientIndex].isActiveMutex.Unlock();
	}
	if (newRemoteClientIndex==-1)
		return UNASSIGNED_SYSTEM_ADDRESS;

	if (block)
	{
		SystemAddress systemAddress;
		systemAddress.FromString(host);
		systemAddress.SetPortHostOrder(remotePort);
		systemAddress.systemIndex=(SystemIndex) newRemoteClientIndex;
		char buffout[128];
		systemAddress.ToString(false,buffout);

		__TCPSOCKET__ sockfd = SocketConnect(buffout, remotePort, socketFamily, bindAddress);
		// Windows RT TODO
#if !defined(WINDOWS_STORE_RT)
		if (sockfd==0)
#endif
		{
			remoteClients[newRemoteClientIndex].isActiveMutex.Lock();
			remoteClients[newRemoteClientIndex].SetActive(false);
			remoteClients[newRemoteClientIndex].isActiveMutex.Unlock();

			failedConnectionAttemptMutex.Lock();
			failedConnectionAttempts.Push(systemAddress, _FILE_AND_LINE_ );
			failedConnectionAttemptMutex.Unlock();

			return UNASSIGNED_SYSTEM_ADDRESS;
		}

		remoteClients[newRemoteClientIndex].socket=sockfd;
		remoteClients[newRemoteClientIndex].systemAddress=systemAddress;

		completedConnectionAttemptMutex.Lock();
		completedConnectionAttempts.Push(remoteClients[newRemoteClientIndex].systemAddress, _FILE_AND_LINE_ );
		completedConnectionAttemptMutex.Unlock();

		return remoteClients[newRemoteClientIndex].systemAddress;
	}
	else
	{
		ThisPtrPlusSysAddr *s = RakNet::OP_NEW<ThisPtrPlusSysAddr>( _FILE_AND_LINE_ );
		s->systemAddress.FromStringExplicitPort(host,remotePort);
		s->systemAddress.systemIndex=(SystemIndex) newRemoteClientIndex;
		if (bindAddress)
			strcpy(s->bindAddress, bindAddress);
		else
			s->bindAddress[0]=0;
		s->tcpInterface=this;
		s->socketFamily=socketFamily;

		// Start the connection thread
		int errorCode;




		errorCode = RakNet::RakThread::Create(ConnectionAttemptLoop, s, threadPriority);

		if (errorCode!=0)
		{
			RakNet::OP_DELETE(s, _FILE_AND_LINE_);
			failedConnectionAttempts.Push(s->systemAddress, _FILE_AND_LINE_ );
		}
		return UNASSIGNED_SYSTEM_ADDRESS;
	}
}
Esempio n. 3
0
void DynDNS::Update(void)
{
    if (connectPhase==CP_IDLE)
        return;

    serverAddress=tcp->HasFailedConnectionAttempt();
    if (serverAddress!=UNASSIGNED_SYSTEM_ADDRESS)
    {
        SetCompleted(RC_TCP_DID_NOT_CONNECT, "Could not connect to DynDNS");
        return;
    }

    serverAddress=tcp->HasCompletedConnectionAttempt();
    if (serverAddress!=UNASSIGNED_SYSTEM_ADDRESS)
    {
        if (connectPhase == CP_CONNECTING_TO_CHECKIP)
        {
            checkIpAddress=serverAddress;
            connectPhase = CP_WAITING_FOR_CHECKIP_RESPONSE;
            tcp->Send("GET\n\n", (unsigned int) strlen("GET\n\n"), serverAddress, false); // Needs 2 newlines! This is not documented and wasted a lot of my time
        }
        else
        {
            connectPhase = CP_WAITING_FOR_DYNDNS_RESPONSE;
            tcp->Send(getString.C_String(), (unsigned int) getString.GetLength(), serverAddress, false);
        }
        phaseTimeout=RakNet::GetTime()+1000;
    }

    if (connectPhase==CP_WAITING_FOR_CHECKIP_RESPONSE && RakNet::GetTime()>phaseTimeout)
    {
        connectPhase = CP_CONNECTING_TO_DYNDNS;
        tcp->CloseConnection(checkIpAddress);
        tcp->Connect("members.dyndns.org", 80, false);
    }
    else if (connectPhase==CP_WAITING_FOR_DYNDNS_RESPONSE && RakNet::GetTime()>phaseTimeout)
    {
        SetCompleted(RC_DYNDNS_TIMEOUT, "DynDNS did not respond");
        return;
    }

    Packet *packet = tcp->Receive();
    if (packet)
    {
        if (connectPhase==CP_WAITING_FOR_DYNDNS_RESPONSE)
        {
            unsigned int i;

            char *result;
            result=strstr((char*) packet->data, "Connection: close");
            if (result!=0)
            {
                result+=strlen("Connection: close");
                while (*result && ((*result=='\r') || (*result=='\n') || (*result==' ')) )
                    result++;
                for (i=0; i < 13; i++)
                {
                    if (strncmp(resultTable[i].code, result, strlen(resultTable[i].code))==0)
                    {
                        if (resultTable[i].resultCode==RC_SUCCESS)
                        {
                            // Read my external IP into myIPStr
                            // Advance until we hit a number
                            while (*result && ((*result<'0') || (*result>'9')) )
                                result++;
                            if (*result)
                            {
                                SystemAddress parser;
                                parser.FromString(result);
                                parser.ToString(false, myIPStr);
                            }
                        }
                        tcp->DeallocatePacket(packet);
                        SetCompleted(resultTable[i].resultCode, resultTable[i].description);
                        break;
                    }
                }
                if (i==13)
                {
                    tcp->DeallocatePacket(packet);
                    SetCompleted(RC_UNKNOWN_RESULT, "DynDNS returned unknown result");
                }
            }
            else
            {
                tcp->DeallocatePacket(packet);
                SetCompleted(RC_PARSING_FAILURE, "Parsing failure on returned string from DynDNS");
            }

            return;
        }
        else
        {
            /*
            HTTP/1.1 200 OK
            Content-Type: text/html
            Server: DynDNS-CheckIP/1.0
            Connection: close
            Cache-Control: no-cache
            Pragma: no-cache
            Content-Length: 105

            <html><head><title>Current IP Check</title></head><body>Current IP Address: 98.1
            89.219.22</body></html>


            Connection to host lost.
            */

            char *result;
            result=strstr((char*) packet->data, "Current IP Address: ");
            if (result!=0)
            {
                result+=strlen("Current IP Address: ");
                SystemAddress myIp;
                myIp.FromString(result);
                myIp.ToString(false, myIPStr);

                char existingHost[65];
                existingHost[0]=0;
                // Resolve DNS we are setting. If equal to current then abort
                RakNetSocket2::DomainNameToIP(host.C_String(), existingHost);
                if (existingHost && strcmp(existingHost, myIPStr)==0)
                {
                    // DynDNS considers setting the IP to what it is already set abuse
                    tcp->DeallocatePacket(packet);
                    SetCompleted(RC_DNS_ALREADY_SET, "No action needed");
                    return;
                }
            }

            tcp->DeallocatePacket(packet);
            tcp->CloseConnection(packet->systemAddress);

            connectPhase = CP_CONNECTING_TO_DYNDNS;
            tcp->Connect("members.dyndns.org", 80, false);
        }
    }

    if (tcp->HasLostConnection()!=UNASSIGNED_SYSTEM_ADDRESS)
    {
        if (connectPhase==CP_WAITING_FOR_DYNDNS_RESPONSE)
        {
            SetCompleted(RC_CONNECTION_LOST_WITHOUT_RESPONSE, "Connection lost to DynDNS during GET operation");
        }
    }
}
int CloudServerHelper::OnJoinCloudResult(
							  Packet *packet,
							  RakNet::RakPeerInterface *rakPeer,
							  RakNet::CloudServer *cloudServer,
							  RakNet::CloudClient *cloudClient,
							  RakNet::FullyConnectedMesh2 *fullyConnectedMesh2,
							  RakNet::TwoWayAuthentication *twoWayAuthentication,
							  RakNet::ConnectionGraph2 *connectionGraph2,
							  const char *rakPeerIpOrDomain,
							  char myPublicIP[32]
							  )
{

	RakNet::MessageID result;
	SystemAddress packetAddress;
	RakNetGUID packetGuid;
	result = packet->data[0];
	packetAddress = packet->systemAddress;
	packetGuid = packet->guid;

	if (result==ID_CONNECTION_REQUEST_ACCEPTED)
	{
		printf("Connected to host %s.\n", rakPeerIpOrDomain);

		// We connected through a public IP.
		// Our external IP should also be public
		// rakPeer->GetExternalID(packetAddress).ToString(false, myPublicIP);

		// Log in to the remote server using two way authentication
		result = RakNet::CloudServerHelper::AuthenticateRemoteServerBlocking(rakPeer, twoWayAuthentication, packetGuid);
		if (result==ID_CONNECTION_LOST || result==ID_DISCONNECTION_NOTIFICATION)
		{
			printf("Connection lost while authenticating.\n");
			printf("Waiting 60 seconds then restarting.\n");
			RakSleep(60000);
			return 2;
		}
		else if (result==ID_TWO_WAY_AUTHENTICATION_OUTGOING_CHALLENGE_TIMEOUT)
		{
			// Other system is not running plugin? Fail
			printf("Remote server did not respond to challenge.\n");
			return 1;
		}
		else if (result==ID_TWO_WAY_AUTHENTICATION_OUTGOING_CHALLENGE_FAILURE)
		{
			printf("Failed remote server challenge.\n");
			return 1;
		}

		RakAssert(result==ID_TWO_WAY_AUTHENTICATION_OUTGOING_CHALLENGE_SUCCESS);

		// Add this system as a server, and to FullyConnectedMesh2 as a participant
		cloudServer->AddServer(packetGuid);
		fullyConnectedMesh2->AddParticipant(packetGuid);
		connectionGraph2->AddParticipant(packetAddress, packetGuid);
	}
	else if (result==ID_ALREADY_CONNECTED)
	{
		printf("Connected to self. DNS entry already points to this server.\n");

		/*
		if (SetHostDNSToThisSystemBlocking()==false)
		return 1;

		// dynDNS gets our public IP when it succeeds
		strcpy( myPublicIP, dynDNS->GetMyPublicIP());
		*/

		// dnsHost is always public, so if I can connect through it that's my public IP
		RakNetSocket2::DomainNameToIP( rakPeerIpOrDomain, myPublicIP );
	}
	else if (result==ID_CONNECTION_ATTEMPT_FAILED)
	{
		
	}
	else
	{
		// Another server is running but we cannot connect to them
		printf("Critical failure\n");
		printf("Reason: ");
		switch (result)
		{
		case ID_REMOTE_SYSTEM_REQUIRES_PUBLIC_KEY:
		case ID_OUR_SYSTEM_REQUIRES_SECURITY:
		case ID_PUBLIC_KEY_MISMATCH:
			printf("Other system is running security code.\n");
			break;
		case ID_CONNECTION_BANNED:
			printf("Banned from the other system.\n");
			break;
		case ID_INVALID_PASSWORD:
			printf("Other system has a password.\n");
			break;
		case ID_INCOMPATIBLE_PROTOCOL_VERSION:
			printf("Different major RakNet version.\n");
			break;
		default:
			printf("N/A\n");
			break;
		}
		return 1;
	}

	// Force the external server address for queries. Otherwise it would report 127.0.0.1 since the client is on localhost
	SystemAddress forceAddress;
	forceAddress.FromString(myPublicIP,RakNet::CloudServerHelper::rakPeerPort);
	cloudServer->ForceExternalSystemAddress(forceAddress);

	if (result==ID_TWO_WAY_AUTHENTICATION_OUTGOING_CHALLENGE_SUCCESS)
	{
		OnConnectionCountChange(rakPeer, cloudClient);
	}
	else
	{
		RakNet::BitStream bs;
		CloudKey cloudKey(CLOUD_SERVER_CONNECTION_COUNT_PRIMARY_KEY,0);
		bs.WriteCasted<unsigned short>(0);
		cloudClient->Post(&cloudKey, bs.GetData(), bs.GetNumberOfBytesUsed(), rakPeer->GetMyGUID());
	}
	return 0;
}