NetRetCode NetSocketListener::Bind()
{
	if (int(m_sockfd) >= 0)
		return NetOk;
		 
	if ((m_sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
	{
		return NetFailed;
	}

	// We are starting the binding process (should really get this atomically)
	// The whole point of m_binding and m_listening are flags which can be set
	// from another thread to help the socket close down gracefully.
	m_binding = true;
	
	// Set up the server address
	NetIpAddress servaddr;
	memset(&servaddr, 0, sizeof(servaddr));
	servaddr.sin_family = AF_INET;
	servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
	servaddr.sin_port = htons(m_port);

	// Bind socket to port
	int bindAttempts = 0;
	while ((bind(m_sockfd, (sockaddr *)&servaddr, sizeof(servaddr)) == -1) && m_binding)
	{
		if ((bindAttempts++ == 5) || (!NetIsAddrInUse))
		{
			m_binding = false;
			return NetFailed;
		}
		else
		{
			AppDebugOut("NETLIB: Failed to bind to port %d\n", m_port);
			NetSleep(bindAttempts * 100);
		}
	}
	
	// If port was 0, let's see what the system assigned
	if (m_port == 0) {
		NetSocketLenType addr_len = sizeof(servaddr);
		if (getsockname(m_sockfd, (sockaddr *)&servaddr, &addr_len) == -1) {
			AppDebugOut("NETLIB: Failed to get system assigned port number\n");
			return NetFailed;
		}
		m_port = ntohs(servaddr.sin_port);
	}
	
	if (m_binding) 
	{
		m_binding = false;
		return NetOk;
	}
	else
		return NetFailed;
}
void NetSocketListener::StopListening()
{
	m_listening = false;
	m_binding = false;
	NetSleep(250);
	if (int(m_sockfd) >= 0)
	{
		shutdown(m_sockfd, 0);
	}

	NetCloseSocket(m_sockfd);
}
Exemple #3
0
static NetCallBackRetType AuthenticationThread(void *ignored)
{
#ifdef WAN_PLAY_ENABLED

    //
    // Every few seconds request the next key to be authenticated

    while( true )
    {
        NetSleep( PERIOD_AUTHENTICATION_RETRY );

        if( MetaServer_IsConnected() )
        {
            char unknownKey[256];
            char clientIp[256];
            int  keyId = -1;
            bool unknownKeyFound = false;

            //
            // Look for a key that isnt yet authenticated

            s_authResultsMutex.Lock();
            for( int i = 0; i < s_authResults.Size(); ++i )
            {
                AuthenticationResult *authResult = s_authResults[i];
                if( authResult->m_authResult == AuthenticationUnknown &&
                    authResult->m_numTries < 5 )
                {
                    strcpy( unknownKey, authResult->m_authKey );
                    strcpy( clientIp, authResult->m_ip );
                    keyId = authResult->m_keyId;
                    authResult->m_numTries++;
                    unknownKeyFound = true;
                    break;
                }
            }        
            s_authResultsMutex.Unlock();
    
        
            //
            // Check the key out

            if( unknownKeyFound )
            {
                int basicResult = Authentication_SimpleKeyCheck(unknownKey);
                if( basicResult < 0 )
                {
                    // The key is in the wrong format
                    Authentication_SetStatus( unknownKey, keyId, basicResult );
                    char *resultString = Authentication_GetStatusString(basicResult);
                    AppDebugOut( "Key failed basic check : %s (result=%s)\n", unknownKey, resultString );
                }
                else if( Authentication_IsDemoKey(unknownKey) )
                {
                    // This is a demo key, and has passed the simple check
                    // Assume its valid from now on
                    Authentication_SetStatus( unknownKey, -1, AuthenticationAccepted );
                    AppDebugOut( "Auth Key accepted as DEMOKEY : %s\n", unknownKey );
                }
                else
                {
                    // Request a proper auth check from the metaserver
                    Directory directory;
                    directory.SetName( NET_METASERVER_MESSAGE );
                    directory.CreateData( NET_METASERVER_COMMAND, NET_METASERVER_REQUEST_AUTH );
                    directory.CreateData( NET_METASERVER_AUTHKEY, unknownKey );
                    directory.CreateData( NET_METASERVER_AUTHKEYID, keyId );
                    directory.CreateData( NET_METASERVER_GAMENAME, APP_NAME );
                    directory.CreateData( NET_METASERVER_GAMEVERSION, APP_VERSION );
                    
                    if( strcmp(clientIp, "unknown") != 0 )
                    {
                        directory.CreateData( NET_METASERVER_IP, clientIp );
                    }

                    MetaServer_SendToMetaServer( &directory );

                    AppDebugOut( "Requesting authentication of key %s\n", unknownKey );
                }
            }
        }
    }

#endif
    
    return 0;
}
Exemple #4
0
static NetCallBackRetType RequestIdentityThread(void *ignored)
{
#ifdef WAN_PLAY_ENABLED
    NetSocketListener *listener = (NetSocketListener *) ignored;
    
    int listenerIndex = GetListenerIndex(listener);
    AppAssert( listenerIndex > -1 );
    
    s_listenersMutex.Lock();
    MatchMakerListener *_listener = s_listeners[listenerIndex];
    AppAssert(_listener);
    s_listenersMutex.Unlock();


    //
    // Generate a uniqueID for this request
    // So we can tell the replies apart

    s_uniqueRequestMutex.Lock();
    int uniqueId = s_uniqueRequestid;
    ++s_uniqueRequestid;
    s_uniqueRequestMutex.Unlock();

    _listener->m_uniqueId = uniqueId;


    //
    // Build our request and convert to a byte stream
    // (only need to do this once and keep re-sending)

    Directory request;
    request.SetName( NET_MATCHMAKER_MESSAGE );
    request.CreateData( NET_METASERVER_COMMAND, NET_MATCHMAKER_REQUEST_IDENTITY );
    request.CreateData( NET_MATCHMAKER_UNIQUEID, uniqueId );
    

    //
    // Open a connection to the MatchMaker service
    // Start sending requests for our ID every few seconds
    // to ensure the connection stays open in the NAT 

    NetSocketSession socket( *listener, s_matchMakerIp, s_matchMakerPort );


    while( true )
    {
        //
        // Stop if We've been asked to 

        if( _listener->m_shutDown )
        {
            break;
        }


        //
        // Update the request with the latest auth data
        
        Directory *clientProps = MetaServer_GetClientProperties();
        request.CreateData( NET_METASERVER_GAMENAME,    clientProps->GetDataString(NET_METASERVER_GAMENAME) );
        request.CreateData( NET_METASERVER_GAMEVERSION, clientProps->GetDataString(NET_METASERVER_GAMEVERSION) );
        request.CreateData( NET_METASERVER_AUTHKEY,     clientProps->GetDataString(NET_METASERVER_AUTHKEY) );
        delete clientProps;

        int requestSize = 0;
        char *requestByteStream = request.Write(requestSize);


        //
        // Send the request

        int numBytesWritten = 0;
        NetRetCode result = socket.WriteData( requestByteStream, requestSize, &numBytesWritten );
        delete [] requestByteStream;

        if( result != NetOk || numBytesWritten != requestSize )
        {
            AppDebugOut( "MatchMaker encountered error sending data\n" );
            break;
        }

        NetSleep( PERIOD_MATCHMAKER_REQUESTID );
    }


    //
    // Shut down the request


    s_listenersMutex.Lock();
    
    if( s_listeners.ValidIndex(listenerIndex) &&
        s_listeners[listenerIndex] == _listener )
    {
        s_listeners.RemoveData(listenerIndex);
    }
    
    s_listenersMutex.Unlock();
    delete _listener;

#endif

    return 0;
}
NetRetCode NetSocket::Connect()
{
	NetRetCode ret = NetOk;
	unsigned long timeout = 0;
	int err = 0;
	struct sockaddr_in *servaddr = &m_to;
	int sockType = SOCK_DGRAM;
	
	m_sockfd = socket(AF_INET, sockType, 0);
	if (!m_sockfd)
	{
		return NetFailed;
	}
	
	memset(servaddr, 0, sizeof(struct sockaddr_in));
	servaddr->sin_family = AF_INET;
	servaddr->sin_port = htons(m_port);
	
	// Resolve dotted IP address
	/* Removed, didn't seem to work for addresses like 127.0.0.1 and 90.0.0.3 */
	//   if (!ncValidInetAddr(ncGetInetAddr(m_hostname,&servaddr->sin_addr.s_addr)))
	//   {
	// Otherwise, resolve host name
	NetHostDetails *pHostent = NetGetHostByName(m_hostname);
	if (!pHostent)
	{
		NetDebugOut("Host address resolution failed for %s", m_hostname);
		return NetFailed;
	}
	else 
	{
		servaddr->sin_addr.s_addr = * ((unsigned long *)pHostent->h_addr_list[0]);
	}
	//   }
	
	// Stash the IP address as an unsigned long in host byte order
	m_ipaddr = servaddr->sin_addr.s_addr;
	
	// Set socket to non - blocking mode
	NetSetSocketNonBlocking(m_sockfd);
	
	// Attempt the connect until we timeout
	while (::connect(m_sockfd, (struct sockaddr *)servaddr, sizeof(*servaddr)) < 0)
	{
		NetDebugOut("Connection error");
		if (NetIsBlockingError(err))
		{
			timeout += 100;
			if (timeout > m_timeout)
			{
				NetDebugOut("Time out connecting to host");
				ret = NetTimedout;
				break;
			}
		}
		else if (NetIsConnected(err))
		{
			NetDebugOut("Already connected");
			break;
		}
		else
		{
			NetDebugOut("Connect to host failed: %d", err);
			ret = NetFailed;
			break;
		}
		NetSleep(100);
	}

	return ret;
}
int _tmain(int argc, _TCHAR* argv[])
{
	_CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);

	srand(NetGetTime());

	Peer* sender; int size;

	NetConnection connection;
	connection.Open(5008);

	NetConnection server;
	server.Open(5007);

	connection.connection.SetRTT(0);
	connection.connection.SetDrop(0);
	connection.connection.SetVariance(0);

	printf("Doing Connection Security Test\n");

	for (int i = 0; i < 50; i++)
	{
		char* buffer = new char[i*6];
		for (int in = 0; in < i*6; in++)
		{
			buffer[in] = rand();
		}
		connection.connection.Send(Address(127,0,0,1,5007), buffer, i*6);
		delete[] buffer;
	}

	NetSleep(1000);//wait to receive messages

	//get all messages out
	char* out;
	while (out = server.Receive(sender, size))
	{
		delete[] out;
	}
	if (server.peers.size() != 0)
		printf("Connection security test failed!!!\n\n");
	else
		printf("Connection security test passed.\n\n");

	auto t = std::thread([](NetConnection* server)
	{
		while (true)
		{
			Peer* sender; int size;
			server->Receive(sender, size);

			if (server->peers.size() > 5)
				return;
		}
	}, &server);

	int status = connection.Connect(Address(127,0,0,1,5007), "testing", 0);
	if (status < 0)
	{
		printf("Connection Test Failed!!!\n");
	}

	NetConnection cons[5];
	for (int i = 0; i < 5; i ++)
	{
		cons[i].Open(5010+i);
		int stat = cons[i].Connect(Address(127,0,0,1,5007), "yo", 0);
		if (stat < 0)
			printf("Connection test failed!\n");
	}

	if (t.joinable())
		t.join();

	printf("Connection Test Successful\n");

	for (int i = 0; i < 5; i++)
	{
		//cons[i].Disconnect();
		cons[i].Close();
	}

	while (server.peers.size() > 1)
	{
		Peer* s; int size;
		server.Receive(s, size);
		NetSleep(1);
	}

	printf("Connections closed successfully\n\n");

	printf("Doing Security Test\n");

	for (int i = 0; i < 50; i++)
	{
		char* buffer = new char[i*6];
		for (int in = 0; in < i*6; in++)
		{
			buffer[in] = rand();
		}
		connection.connection.Send(connection.peers.begin()->second->connection.remoteaddr, buffer, i*6);
		delete[] buffer;
	}

	NetSleep(1000);//wait to receive messages

	//get all messages out
	//char* out;
	while (out = server.Receive(sender, size))
	{
		delete[] out;
	}
	printf("Well, we didnt crash, so security test probably didn't fail...\n\n");


	connection.connection.SetRTT(0.05);
	connection.connection.SetDrop(0.1);
	connection.connection.SetVariance(0.02);

	//start testing
	printf("Testing reliable messages...\n");
	int num = 50;
	while(num-- > 0)
	{
		int data[200];
		for (int i = 0; i < 200; i++)
		{
			data[i] = rand();
		}
		connection.SendReliable((char*)data, sizeof(data));

		//ok, now check
		Peer* sender; int size;
		while (true)
		{
			char* buffer = server.Receive(sender, size);
			if (buffer)
			{
				if (size == sizeof(data))
				{
					for (int i = 0; i < 200; i++)
					{
						assert(((int*)buffer)[i] == data[i]);
					}
					//printf("one good\n");
				}
				else
				{
					printf("Bad message size!!!\n");
				}
				delete[] buffer;
				break;
			}
		}
	}
	printf("Reliable message sending passed!\n\n");

	printf("Testing reliable ordered messages...\n");
	num = 50;
	int data[20][200];
	for (int i = 0; i < 20; i++)
	{
		for (int i2 = 0; i2 < 200; i2++)
		{
			data[i][i2] = rand();
		}
		data[i][0] = i;
		connection.peers.begin()->second->connection.SendReliableOrdered((char*)data[i], sizeof(data[i]), 5);
	}


	//ok, now check
	num = 0;
	while (num < 20)
	{
		char* buffer = server.Receive(sender, size);
		if (buffer)
		{
			if (size == sizeof(data[0]))
			{
				for (int i = 0; i < 200; i++)
				{
					assert(((int*)buffer)[i] == data[num][i]);
				}
				//printf("one good\n");
			}
			else
			{
				printf("Bad message size!!!\n");
			}
			num++;
			delete[] buffer;
		}
	}
	printf("Ordered Reliable Message Sending Passed!\n\n");

	printf("Testing Split Reliable Ordered Messages...\n");
	num = 50;
	int data2[20][500];
	for (int i = 0; i < 20; i++)
	{
		for (int i2 = 0; i2 < 500; i2++)
		{
			data2[i][i2] = rand();
		}
		data2[i][0] = i;
		connection.peers.begin()->second->connection.SendReliableOrdered((char*)data2[i], sizeof(data2[i]), 5);
	}


	//ok, now check
	//Peer* sender; int size;
	num = 0;
	while (num < 20)
	{
		char* buffer = server.Receive(sender, size);
		if (buffer)
		{
			if (size == sizeof(data2[0]))
			{
				for (int i = 0; i < 500; i++)
				{
					assert(((int*)buffer)[i] == data2[num][i]);
				}
			}
			else
			{
				printf("Bad message size!!!\n");
			}
			num++;
			delete[] buffer;
		}
	}
	printf("Ordered Split Reliable Message Sending Passed!\n\n");

	printf("Testing Reliable Message Splitting...\n");
	//test splitting
	num = 50;
	while(num-- > 0)
	{
		int data[800];
		for (int i = 0; i < 800; i++)
		{
			data[i] = rand();
		}
		connection.SendReliable((char*)data, sizeof(data));

		//ok, now check
		Peer* sender; int size;
		while (true)
		{
			char* buffer = server.Receive(sender, size);
			if (buffer)
			{
				if (size == sizeof(data))
				{
					for (int i = 0; i < 800; i++)
					{
						assert(((int*)buffer)[i] == data[i]);
					}
				}
				else
				{
					printf("Bad message size!!!\n");
				}
				delete[] buffer;
				break;
			}
		}
	}
	printf("Reliable Message Splitting Sending Passed!\n\n");

	connection.connection.SetRTT(0);
	connection.connection.SetDrop(0);
	connection.connection.SetVariance(0);

	//test unreliable
	printf("Testing unreliable message sending...\n");
	//test splitting
	num = 50;
	while(num-- > 0)
	{
		int data[200];
		for (int i = 0; i < 200; i++)
		{
			data[i] = rand();
		}
		connection.Send((char*)data, sizeof(data));

		//ok, now check
		Peer* sender; int size;
		while (true)
		{
			char* buffer = server.Receive(sender, size);
			if (buffer)
			{
				if (size == sizeof(data))
				{
					for (int i = 0; i < 200; i++)
					{
						assert(((int*)buffer)[i] == data[i]);
					}
				}
				else
				{
					printf("Bad message size!!!\n");
				}
				delete[] buffer;
				break;
			}
		}
	}
	printf("Unreliable message sending passed!\n\n");

	//test unreliable splitting
	printf("Testing unreliable message splitting...\n");
	num = 50;
	while(num-- > 0)
	{
		int data[800];
		for (int i = 0; i < 800; i++)
		{
			data[i] = rand();
		}
		connection.Send((char*)data, sizeof(data));

		//ok, now check
		Peer* sender; int size;
		while (true)
		{
			char* buffer = server.Receive(sender, size);
			if (buffer)
			{
				if (size == sizeof(data))
				{
					for (int i = 0; i < 800; i++)
					{
						assert(((int*)buffer)[i] == data[i]);
					}
				}
				else
				{
					printf("Bad message size!!!\n");
				}
				delete[] buffer;
				break;
			}
		}
	}
	printf("Unreliable message splitting sending passed!\n\n");

	//test packet coalesing
	printf("Testing unreliable message coalescing...\n");
	num = 50;
	while(num-- > 0)
	{
		int data[121];
		for (int i = 0; i < 121; i++)
		{
			data[i] = rand();
		}
		connection.Send((char*)data, sizeof(data));
		connection.Send((char*)data, sizeof(data));
		connection.Send((char*)data, sizeof(data));

		connection.SendPackets();//force send

		//ok, now check
		Peer* sender; int size;
		for (int i = 0; i < 3; i++)
		{
			while (true)
			{
				char* buffer = server.Receive(sender, size);
				if (buffer)
				{
					if (size == sizeof(data))
					{
						for (int i = 0; i < 121; i++)
						{
							assert(((int*)buffer)[i] == data[i]);
						}
					}
					else
					{
						printf("Bad message size!!!\n");
					}
					delete[] buffer;
					break;
				}
			}
		}
	}
	printf("Unreliable message coalescing passed!\n\n");

	printf("Testing Disconnection...\n");
	connection.Disconnect();
	while (true)
	{
		Peer* sender; int size;
		server.Receive(sender, size);

		if (server.peers.size() == 0)
			break;
	}
	printf("Disconnection successful!\n");

	//while (true)
	NetSleep(10000);

	return 0;
}