Beispiel #1
0
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// UDP Layer must be initialized
// theIp and thePort cannot be 0 (Zero)
// Based on an IP and port, the function will return the amount of free space 
// of a peer's buffer.
int gsUdpEngineGetPeerOutBufferFreeSpace(unsigned int theIp, unsigned short thePort)
{
	GSUdpEngineObject *aUdp = gsUdpEngineGetEngine();
	GSUdpRemotePeer aRemotePeer, *aRemotePeerFound;
	int index;
	GS_ASSERT(aUdp->mInitialized);
	GS_ASSERT(theIp);
	GS_ASSERT(thePort);
	if (!aUdp->mInitialized)
	{
		gsDebugFormat(GSIDebugCat_Common, GSIDebugType_Network, GSIDebugLevel_Debug,
			"[Udp Engine] Engine not initialized\n");
		return 0;
	}

	aRemotePeer.mAddr = theIp;
	aRemotePeer.mPort = thePort;
	index = ArraySearch(aUdp->mRemotePeers, &aRemotePeer, gsUdpRemotePeerCompare, 0, 0);
	if (index != NOT_FOUND)
	{
		aRemotePeerFound = (GSUdpRemotePeer *)ArrayNth(aUdp->mRemotePeers, index);
		return gt2GetOutgoingBufferFreeSpace(aRemotePeerFound->mConnection);
	}
	return 0;
}
Beispiel #2
0
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// UDP Layer must be initialized
// Used obtain the peer's state 
// theIp and thePort cannot be 0 (Zero)
GSUdpErrorCode gsUdpEngineGetPeerState(unsigned int theIp, unsigned short thePort, GSUdpPeerState *thePeerState)
{
	GSUdpEngineObject *aUdp = gsUdpEngineGetEngine();
	GSUdpRemotePeer aPeer, *aPeerFound;
	int index;
	GS_ASSERT(aUdp->mInitialized);
	GS_ASSERT(theIp);
	GS_ASSERT(thePort);
	GS_ASSERT(thePeerState != NULL);
	if (!aUdp->mInitialized)
	{
		gsDebugFormat(GSIDebugCat_Common, GSIDebugType_State, GSIDebugLevel_Debug, 
			"[Udp Engine] Engine not initialized\n");
		*thePeerState = GS_UDP_PEER_CLOSED;
		return GS_UDP_NOT_INITIALIZED;
	}

	aPeer.mAddr = theIp;
	aPeer.mPort = thePort;
	index = ArraySearch(aUdp->mRemotePeers, &aPeer, gsUdpRemotePeerCompare, 0, 0);
	if (index == NOT_FOUND)
	{
		*thePeerState = GS_UDP_PEER_CLOSED;
		return GS_UDP_NO_ERROR;
	}
	
	aPeerFound = (GSUdpRemotePeer *)ArrayNth(aUdp->mRemotePeers, index);

	*thePeerState = (GSUdpPeerState)gt2GetConnectionState(aPeerFound->mConnection);
	return GS_UDP_NO_ERROR;
}
Beispiel #3
0
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// UDP Layer must be initialized
// theIp and thePort cannot be 0 (Zero)
// Rejects a Peer's request for communication 
// Should only be used by App
GSUdpErrorCode gsUdpEngineRejectPeer(unsigned int theIp, unsigned short thePort)
{
	GSUdpRemotePeer aRemotePeer;	
	GSUdpEngineObject *aUdp = gsUdpEngineGetEngine();
	int index;
	GS_ASSERT(aUdp->mInitialized);
	GS_ASSERT(theIp);
	GS_ASSERT(thePort);
	if (!aUdp->mInitialized)
	{
		gsDebugFormat(GSIDebugCat_Common, GSIDebugType_Network, GSIDebugLevel_Debug,
			"[Udp Engine] Engine not initialized\n");
		return GS_UDP_NETWORK_ERROR;
	}

	if (theIp == 0 || thePort == 0)
	{
		gsDebugFormat(GSIDebugCat_Common, GSIDebugType_Network, GSIDebugLevel_Debug,
			"[Udp Engine] Invalid parameter(s), check ip, port\n");
		return GS_UDP_PARAMETER_ERROR;
	}

	// Find the connection to reject in our array of peers
	aRemotePeer.mAddr = theIp;
	aRemotePeer.mPort = thePort;
	index = ArraySearch(aUdp->mRemotePeers, &aRemotePeer, gsUdpRemotePeerCompare, 0, 0);
	if (index != NOT_FOUND)
	{
		GSUdpRemotePeer *aPeerFound = (GSUdpRemotePeer *)ArrayNth(aUdp->mRemotePeers, index);
		gt2Reject(aPeerFound->mConnection, NULL, 0);
		ArrayDeleteAt(aUdp->mRemotePeers, index);
	}
	return GS_UDP_NO_ERROR;
}
Beispiel #4
0
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// Pings are passed on to higher level app or message handlers
void gsUdpPingRoutingCB(GT2Connection theConnection, int theLatency)
{
	GSUdpEngineObject *aUdp = gsUdpEngineGetEngine();
	int index, len;
	char anAddr[GS_IP_ADDR_AND_PORT];

	gsDebugFormat(GSIDebugCat_Common, GSIDebugType_Network, GSIDebugLevel_Comment, 
		"[Udp Engine] Received ping from %s\n", gt2AddressToString(gt2GetRemoteIP(theConnection), 
		gt2GetRemotePort(theConnection), anAddr));
	len = ArrayLength(aUdp->mMsgHandlers);
	for (index = 0; index < len; index++)
	{
		GSUdpMsgHandler *aHandler = (GSUdpMsgHandler *)ArrayNth(aUdp->mMsgHandlers, index);
		if (aHandler->mPingReply)
		{			
			gsDebugFormat(GSIDebugCat_Common, GSIDebugType_Network, GSIDebugLevel_Comment, 
				"[Udp Engine] Passed to message handler\n");
			aHandler->mPingReply(gt2GetRemoteIP(theConnection), gt2GetRemotePort(theConnection), (unsigned int)theLatency, aHandler->mUserData);
			return;
		}	
	}

	if (aUdp->mAppPingReply)
	{
		gsDebugFormat(GSIDebugCat_Common, GSIDebugType_Network, GSIDebugLevel_Comment, 
			"[Udp Engine] Passed to app\n");
		aUdp->mAppPingReply(gt2GetRemoteIP(theConnection), gt2GetRemotePort(theConnection), (unsigned int)theLatency, aUdp->mAppUserData);
	}
	GSI_UNUSED(anAddr);
}
Beispiel #5
0
/* SetElement
 * Sets the element at pos to the contents of elem
 */
static void SetElement(DArray array, const void *elem, int pos)
{
	GS_ASSERT(array)			// safety check -mj Oct 31st
	GS_ASSERT(elem)	
	GS_ASSERT(array->elemsize)	

	memcpy(ArrayNth(array,pos), elem, (size_t)array->elemsize);
}
Beispiel #6
0
void *TableLookup(HashTable table, const void *elemKey)
{
	int hash, itempos;

	hash = table->hashfn(elemKey, table->nbuckets);
	itempos = ArraySearch(table->buckets[hash], elemKey, table->compfn, 0, 0);
	if (itempos == NOT_FOUND)
		return NULL;
	else
		return ArrayNth(table->buckets[hash], itempos);
}
Beispiel #7
0
GPResult
gpiPeerSendMessages(
  GPConnection * connection,
  GPIPeer * peer
)
{
	GPIBool connClosed;
	GPIMessage * message;
	GPResult result;

	GS_ASSERT(peer);
	if (!peer)
		return GP_NETWORK_ERROR;
	// Only send messages if there's nothing waiting in the output buffer.
	//////////////////////////////////////////////////////////////////////
	if(peer->outputBuffer.len)
		return GP_NO_ERROR;

	// Send outgoing messages.
	//////////////////////////
	while(ArrayLength(peer->messages))
	{
		// Get the first message.
		/////////////////////////
		message = (GPIMessage *)ArrayNth(peer->messages, 0);

		// Send as much as possible.
		////////////////////////////
		//result = gpiSendFromBuffer(connection, peer->sock, &message->buffer, &connClosed, GPIFalse, "PR");
		result = gpiSendBufferToPeer(connection, peer->ip, peer->port, &message->buffer, &connClosed, GPIFalse);
		if(connClosed || (result != GP_NO_ERROR))
		{
			peer->state = GPI_PEER_DISCONNECTED;
			return GP_NO_ERROR;
		}

		// Did we not send it all?
		//////////////////////////
		if(message->buffer.pos != message->buffer.len)
			break;

		// Remove the message.
		//////////////////////
		ArrayDeleteAt(peer->messages, 0);
	}

	return GP_NO_ERROR;
}
Beispiel #8
0
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// Lets the App and Message Handlers know a peer left
void gsUdpClosedRoutingCB(GT2Connection theConnection, GT2CloseReason reason)
{
	GSUdpEngineObject *aUdp = gsUdpEngineGetEngine();
	GSUdpRemotePeer aRemotePeer;
	int index, len;
	GSUdpCloseReason aReason;
	char anAddr[GS_IP_ADDR_AND_PORT];

	if (reason == GT2CommunicationError || reason == GT2SocketError)
		aReason = GS_UDP_CLOSED_BY_COMM_ERROR;
	else if (reason == GT2NotEnoughMemory)
		aReason = GS_UDP_CLOSED_BY_LOW_MEM;
	else 
		aReason = (GSUdpCloseReason)reason;

	gsDebugFormat(GSIDebugCat_Common, GSIDebugType_Network, GSIDebugLevel_Comment, 
		"[Udp Engine] Connection closed to %s\n", gt2AddressToString(gt2GetRemoteIP(theConnection), 
		gt2GetRemotePort(theConnection), anAddr));
	len = ArrayLength(aUdp->mMsgHandlers);
	for (index = 0; index < len; index++)
	{
		GSUdpMsgHandler *aHandler = (GSUdpMsgHandler *)ArrayNth(aUdp->mMsgHandlers, index);
		if (aHandler->mClosed)
		{			
			gsDebugFormat(GSIDebugCat_Common, GSIDebugType_Network, GSIDebugLevel_Comment, 
				"[Udp Engine] Connection closed: passed to message handler\n");
			aHandler->mClosed(gt2GetRemoteIP(theConnection), gt2GetRemotePort(theConnection), aReason, aHandler->mUserData);
		}	
	}
	
	if (aUdp->mAppClosed)
	{
		gsDebugFormat(GSIDebugCat_Common, GSIDebugType_Network, GSIDebugLevel_Comment, 
			"[Udp Engine] Connection closed: passed to app\n");
		aUdp->mAppClosed(gt2GetRemoteIP(theConnection), gt2GetRemotePort(theConnection), aReason, aUdp->mAppUserData);
	}

	aRemotePeer.mConnection = theConnection;
	index = ArraySearch(aUdp->mRemotePeers, &aRemotePeer, gsUdpRemotePeerCompare2, 0, 0);
	if (index != NOT_FOUND)
	{
		ArrayDeleteAt(aUdp->mRemotePeers, index);
	}
	GSI_UNUSED(anAddr);
}
Beispiel #9
0
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// Lets the Message Handler and App know about network errors 
void gsUdpSocketError(GT2Socket theSocket)
{
	int i, len;
	GSUdpEngineObject *aUdp = gsUdpEngineGetEngine();
	
	gsDebugFormat(GSIDebugCat_Common, GSIDebugType_Network, GSIDebugLevel_Comment, 
		"[Udp Engine] Socket error, passing to app and message handlers\n");
	if (aUdp->mAppNetworkError)
		aUdp->mAppNetworkError(GS_UDP_NETWORK_ERROR, aUdp->mAppUserData);
	len = ArrayLength(aUdp->mMsgHandlers);
	for (i = 0; i < len; i++)
	{
		GSUdpMsgHandler *aMsgHandler = (GSUdpMsgHandler *)ArrayNth(aUdp->mMsgHandlers, i);
		if (aMsgHandler->mNetworkError)
			aMsgHandler->mNetworkError(GS_UDP_NETWORK_ERROR, aMsgHandler->mUserData);
	}
	GSI_UNUSED(theSocket);
}
Beispiel #10
0
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// Any data received prompts the UDP layer to first find a higher level 
// message handler to handle the data.  If there was no message handler 
// found, the data is passed to the higher level app.
void gsUdpReceivedRoutingCB(GT2Connection theConnection, GT2Byte *theMessage, int theMessageLen, 
							GT2Bool reliable)
{
	GSUdpEngineObject *aUdp = gsUdpEngineGetEngine();
	GSUdpMsgHandler aHandler;
	int index;
	char anAddr[GS_IP_ADDR_AND_PORT];	

	gsDebugFormat(GSIDebugCat_Common, GSIDebugType_Network, GSIDebugLevel_Comment, 
		"[Udp Engine] Received data from %s\n", gt2AddressToString(gt2GetRemoteIP(theConnection), 
		gt2GetRemotePort(theConnection), anAddr));
	//If there is a handler, pass it to the handler
	//The header should not be stripped off
	if (theMessageLen >= GS_UDP_MSG_HEADER_LEN)
	{    
		memcpy(aHandler.mHeader, theMessage, GS_UDP_MSG_HEADER_LEN);

		index = ArraySearch(aUdp->mMsgHandlers, &aHandler, gsUdpMsgHandlerCompare2, 0, 0);
		if (index != NOT_FOUND)
		{
			GSUdpMsgHandler *aHandlerFound = (GSUdpMsgHandler *)ArrayNth(aUdp->mMsgHandlers, index);
			if (aHandlerFound->mReceived)
			{
				gsDebugFormat(GSIDebugCat_Common, GSIDebugType_Network, GSIDebugLevel_Comment, 
					"[Udp Engine] Passed to message handler\n");
				aHandlerFound->mReceived(gt2GetRemoteIP(theConnection), gt2GetRemotePort(theConnection), 
					theMessage + GS_UDP_MSG_HEADER_LEN, (unsigned int)(theMessageLen - GS_UDP_MSG_HEADER_LEN), reliable, aHandlerFound->mUserData);
				return;
			}
		}
	}

	if (aUdp->mAppRecvData) 
	{
		gsDebugFormat(GSIDebugCat_Common, GSIDebugType_Network, GSIDebugLevel_Comment, 
			"[Udp Engine] Passed to app\n");
		aUdp->mAppRecvData(gt2GetRemoteIP(theConnection), gt2GetRemotePort(theConnection), theMessage, (unsigned int)theMessageLen, reliable,
			aUdp->mAppUserData);
	}
	GSI_UNUSED(anAddr);
}
Beispiel #11
0
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// UDP Layer must be initialized
// theIp and thePort cannot be 0 (Zero)
// Accepts a Peer's request for communication 
// Should only be used by App
GSUdpErrorCode gsUdpEngineAcceptPeer(unsigned int theIp, unsigned short thePort)
{	
	GSUdpRemotePeer aRemotePeer;	
	GSUdpEngineObject *aUdp = gsUdpEngineGetEngine();
	int index;
	GS_ASSERT(aUdp->mInitialized);
	GS_ASSERT(theIp);
	GS_ASSERT(thePort);
	if (!aUdp->mInitialized)
	{
		gsDebugFormat(GSIDebugCat_Common, GSIDebugType_Network, GSIDebugLevel_Debug,
			"[Udp Engine] Engine not initialized\n");
		return GS_UDP_NETWORK_ERROR;
	}

	if (theIp == 0 || thePort == 0)
	{
		gsDebugFormat(GSIDebugCat_Common, GSIDebugType_Network, GSIDebugLevel_Debug,
			"[Udp Engine] Invalid parameter(s), check ip, port\n");
		return GS_UDP_PARAMETER_ERROR;
	}

	aRemotePeer.mAddr = theIp;
	aRemotePeer.mPort = thePort;
	index = ArraySearch(aUdp->mRemotePeers, &aRemotePeer, gsUdpRemotePeerCompare, 0, 0);
	if (index != NOT_FOUND)
	{
		GT2ConnectionCallbacks aCallbacks;
		
		GSUdpRemotePeer *aPeerFound = (GSUdpRemotePeer *)ArrayNth(aUdp->mRemotePeers, index);
		
		aCallbacks.closed = gsUdpClosedRoutingCB;
		aCallbacks.connected = gsUdpConnectedRoutingCB;
		aCallbacks.ping = gsUdpPingRoutingCB;
		aCallbacks.received = gsUdpReceivedRoutingCB;
		
		gt2Accept(aPeerFound->mConnection, &aCallbacks);
	}
	return GS_UDP_NO_ERROR;
}
Beispiel #12
0
GPResult gpiProcessNp(GPConnection * connection)
{
    int i, ret=0;
    GPIConnection * iconnection = (GPIConnection*)*connection;
    npIdLookupTrans * transaction;

    // Check for uninitialized transaction darray
    //////////////////////////////////////////////
    if (!iconnection->npTransactionList)
        return GP_NO_ERROR;

    // Need to process Sysutil for the Async lookups
    /////////////////////////////////////////////////
    if (ArrayLength(iconnection->npTransactionList) > 0)
        cellSysutilCheckCallback();

    // Loop through all current transactions, check if complete
    ///////////////////////////////////////////////////////////
    for (i=0; i < ArrayLength(iconnection->npTransactionList); i++)
    {
        // Grab next transaction in the list
        /////////////////////////////////////    
        transaction = (npIdLookupTrans *)ArrayNth(iconnection->npTransactionList, i);

        if (!transaction->npLookupDone)
        {
            if (sceNpLookupPollAsync(transaction->npTransId, &ret)==0)
                transaction->npLookupDone = gsi_true;
        }
        else
        {
            if (ret<0)
            {
                gsDebugFormat(GSIDebugCat_GP, GSIDebugType_Misc, GSIDebugLevel_HotError,
                    "PS3AddToNpBlockList: sceNpLookupWaitAsync. ret = 0x%x\n", ret);
                if (ret == (int)SCE_NP_COMMUNITY_SERVER_ERROR_NO_SUCH_USER_NPID)
                {
                    gsDebugFormat(GSIDebugCat_GP, GSIDebugType_Misc, GSIDebugLevel_HotError,
                        "PS3AddToNpBlockList: Player '%s' is not an NP user.\n", 
                        transaction->npIdForAdd->handle.data);
                }
            }
            else
            {
                // Found an NpId, try to add
                /////////////////////////////                 
                ret = sceNpBasicAddBlockListEntry(transaction->npIdForAdd);
                if (ret == (int)SCE_NP_BASIC_ERROR_BUSY)
                {
                    // Oh nice, NP is too busy to help us.... keep on trying
                    /////////////////////////////////////////////////////////                         
                    gsDebugFormat(GSIDebugCat_GP, GSIDebugType_Misc, GSIDebugLevel_Comment,
                        "PS3AddToNpBlockList: SCE_NP_BASIC_ERROR_BUSY. continue trying to add to NP\n"); 
                    return GP_NO_ERROR;
                }
                else if ( ret < 0 ) 
                {
                    gsDebugFormat(GSIDebugCat_GP, GSIDebugType_Misc, GSIDebugLevel_HotError,
                        "PS3AddToNpBlockList: sceNpBasicAddBlockListEntry() failed. ret = 0x%x\n", ret); 
                }                
                else
                {
                    gsDebugFormat(GSIDebugCat_GP, GSIDebugType_Misc, GSIDebugLevel_Comment,
                        "PS3AddToNpBlockList: Player '%s' added to NP Block list.\n", 
                        transaction->npIdForAdd->handle.data); 
                }
            }

            ret = sceNpLookupDestroyTransactionCtx(transaction->npTransId);
            if (ret<0)
            {
                gsDebugFormat(GSIDebugCat_GP, GSIDebugType_Misc, GSIDebugLevel_HotError,
                    "PS3AddToNpBlockList: sceNpLookupDestroyTransactionCtx() failed. ret = 0x%x\n", ret); 
            }

            // Delete Transaction when its complete
            ////////////////////////////////////////
            ArrayDeleteAt(iconnection->npTransactionList, i);
        }
    }

    return GP_NO_ERROR;
}
Beispiel #13
0
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// UDP Layer must be initialized
// Sends a message to a peer using IP and Port
// An empty header constitutes the app sending this message.
// theIp and thePort cannot be 0 (Zero)
// 
// WARNING: Messages should not be greater than the outgoing buffer size minus the header 
// and the 7 byte header for reliable messages (used for internal gt2 operations). Most
// UDP fragmentation occurs if messages are bigger than 1500 bytes.  Also, some routers are 
// known to drop those packets that are larger than 1500 bytes.  The recommended outgoing 
// buffer size is the default (1460).  So take that, and subtract 16 for message handler header
// and reliable message header (if sending data reliably).
// freeSpace = 1460 - 16 - 7
GSUdpErrorCode gsUdpEngineSendMessage(unsigned int theIp, unsigned short thePort, 
									  char theHeader[GS_UDP_MSG_HEADER_LEN], unsigned char *theMsg, 
									  unsigned int theMsgLen, gsi_bool theReliable)
{
	GSUdpEngineObject *aUdp = gsUdpEngineGetEngine();
	int aTotalMessageLen, index;
	GSUdpRemotePeer aRemotePeer, *aRemotePeerFound;
	GT2Byte *fullMessage;
	GT2Result aResult;
	GS_ASSERT(aUdp->mInitialized);
	GS_ASSERT(theIp);
	GS_ASSERT(thePort);
	if (!aUdp->mInitialized)
	{
		gsDebugFormat(GSIDebugCat_Common, GSIDebugType_Network, GSIDebugLevel_Debug,
			"[Udp Engine] Engine not initialized\n");
		return GS_UDP_NETWORK_ERROR;
	}

	// Messages being sent with an empty header are treated as app messages
	if (!theHeader[0])
		aTotalMessageLen = (int)theMsgLen;
	else 
		aTotalMessageLen = (int)(GS_UDP_MSG_HEADER_LEN + theMsgLen);

	aRemotePeer.mAddr = theIp;
	aRemotePeer.mPort = thePort;

	index = ArraySearch(aUdp->mRemotePeers, &aRemotePeer, gsUdpRemotePeerCompare, 0, 0);
	if (index == NOT_FOUND)
	{
		char anAddr[GS_IP_ADDR_AND_PORT];
		gt2AddressToString(theIp, thePort, anAddr);
		gsDebugFormat(GSIDebugCat_Common, GSIDebugType_Network, GSIDebugLevel_WarmError,
			"[Udp Engine] address not found for sending message\n", anAddr);
		return GS_UDP_ADDRESS_ERROR;
	}
	else
	{
		aRemotePeerFound = (GSUdpRemotePeer *)ArrayNth(aUdp->mRemotePeers, index);
	}

	if (aTotalMessageLen > gt2GetOutgoingBufferSize(aRemotePeerFound->mConnection) && theReliable)
	{
		gsDebugFormat(GSIDebugCat_Common, GSIDebugType_Network, GSIDebugLevel_WarmError,
			"[Udp Engine] Message Size too large, dropping message\n");
		return GS_UDP_MSG_TOO_BIG;
	}

	fullMessage = (GT2Byte *)gsimalloc((unsigned long)aTotalMessageLen);
	memcpy(fullMessage, theHeader, GS_UDP_MSG_HEADER_LEN);
	memcpy(fullMessage + GS_UDP_MSG_HEADER_LEN, theMsg, theMsgLen);
	// Send the message 
	// reliable messages will be kept in the outgoing buffers till they are sent
	aResult = gt2Send(aRemotePeerFound->mConnection, fullMessage, aTotalMessageLen, theReliable);
	gsifree(fullMessage);

	if (aResult != GT2Success)
		return GS_UDP_SEND_FAILED;
	return GS_UDP_NO_ERROR;
}
Beispiel #14
0
/* FreeElement
 * Frees the element at position N in the array
 */
static void FreeElement(DArray array, int n)
{
	if (array->elemfreefn != NULL)
		array->elemfreefn(ArrayNth(array,n));
}
Beispiel #15
0
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// UDP Layer must be initialized
// theIp and thePort cannot be 0 (Zero)
// Starts a request to open a communication channel with another peer based on 
// IP and port.  
GSUdpErrorCode gsUdpEngineStartTalkingToPeer(unsigned int theIp, unsigned short thePort,
									  char theInitMsg[GS_UDP_MSG_HEADER_LEN], int timeOut)
{
	char anAddr[GS_IP_ADDR_AND_PORT];
	GSUdpRemotePeer aRemotePeer;	
	GSUdpMsgHandler aHandler;
	GSUdpEngineObject *aUdp = gsUdpEngineGetEngine();
	GT2ConnectionCallbacks aCallbacks;
	int index;
	GS_ASSERT(aUdp->mInitialized);
	GS_ASSERT(theIp);
	GS_ASSERT(thePort);

	if (!aUdp->mInitialized)
	{
		gsDebugFormat(GSIDebugCat_Common, GSIDebugType_Network, GSIDebugLevel_Debug,
			"[Udp Engine] Engine not initialized\n");
		return GS_UDP_NETWORK_ERROR;
	}
	
	if (theIp == 0 || thePort == 0)
	{
		gsDebugFormat(GSIDebugCat_Common, GSIDebugType_Network, GSIDebugLevel_Debug,
			"[Udp Engine] Invalid parameter(s), check ip, port");
		return GS_UDP_PARAMETER_ERROR;
	}
	
	aRemotePeer.mAddr = theIp;  // In Network Byte Order for GT2
	aRemotePeer.mPort = thePort;  // In Host Byte Order for GT2

	index = ArraySearch(aUdp->mRemotePeers, &aRemotePeer, gsUdpRemotePeerCompare, 0, 0);
	if (index != NOT_FOUND)
	{
		GSUdpRemotePeer *aPeerFound = (GSUdpRemotePeer *)ArrayNth(aUdp->mRemotePeers, index);
		GT2ConnectionState aState = gt2GetConnectionState(aPeerFound->mConnection);
		if (aState == GT2Connected)
		{
			gsDebugFormat(GSIDebugCat_Common, GSIDebugType_Network, GSIDebugLevel_Debug,
				"[Udp Engine] Engine is already talking to remote address\n");
			return GS_UDP_ADDRESS_ALREADY_IN_USE;
		}
		else if (aState == GT2Connecting)
		{
			memcpy(aHandler.mInitialMsg, theInitMsg, GS_UDP_MSG_HEADER_LEN);
			
			index = ArraySearch(aUdp->mMsgHandlers, &aHandler, gsUdpMsgHandlerCompare, 0, 0);
			if (index != NOT_FOUND)
			{
				GSUdpMsgHandler *aHandlerFound = (GSUdpMsgHandler *)ArrayNth(aUdp->mMsgHandlers, index);
				ArrayAppend(aHandlerFound->mPendingConnections, aPeerFound);
			}
		}
	}	
	else
	{
		gt2AddressToString(theIp, thePort, anAddr);
		aCallbacks.closed = gsUdpClosedRoutingCB;
		aCallbacks.connected = gsUdpConnectedRoutingCB;
		aCallbacks.ping = gsUdpPingRoutingCB;
		aCallbacks.received = gsUdpReceivedRoutingCB;

		// start the connect without blocking since we want the engine to be as asynchronous as possible
		gt2Connect(aUdp->mSocket, &aRemotePeer.mConnection, anAddr, (unsigned char *)theInitMsg, GS_UDP_MSG_HEADER_LEN, timeOut, &aCallbacks, GT2False);

		ArrayAppend(aUdp->mRemotePeers, &aRemotePeer);
		
		memcpy(aHandler.mInitialMsg, theInitMsg, GS_UDP_MSG_HEADER_LEN);
		
		index = ArraySearch(aUdp->mMsgHandlers, &aHandler, gsUdpMsgHandlerCompare, 0, 0);
		if (index != NOT_FOUND)
		{
			GSUdpRemotePeer *aRemotePeerPtr = (GSUdpRemotePeer *)ArrayNth(aUdp->mRemotePeers, ArrayLength(aUdp->mRemotePeers) - 1);
			GSUdpMsgHandler *aHandlerFound = (GSUdpMsgHandler *)ArrayNth(aUdp->mMsgHandlers, index);
			ArrayAppend(aHandlerFound->mPendingConnections, &aRemotePeerPtr);
		}
		else
		{
			aUdp->mAppPendingConnections++;
		}
	}
	return GS_UDP_NO_ERROR;
}
Beispiel #16
0
void
gpiRemovePeer(
  GPConnection * connection,
  GPIPeer * peer
)
{
	GPIPeer * pprev;
	GPIConnection * iconnection = (GPIConnection*)*connection;
	GPIMessage * message;

	GS_ASSERT(peer != NULL);
	if (peer == NULL)
		return;

	GS_ASSERT(iconnection->peerList);
	if (iconnection->peerList == NULL)
		return;
	// Check if this is the first peer.
	///////////////////////////////////
	if(iconnection->peerList == peer)
	{
		iconnection->peerList = peer->pnext;
	}
	else
	{
		// Find the previous peer.
		//////////////////////////
		for(pprev = iconnection->peerList ; pprev->pnext != peer ; pprev = pprev->pnext)
		{
			if(pprev->pnext == NULL)
			{
				// Can't find this peer in the list!
				////////////////////////////////////
				assert(0);
				gsDebugFormat(GSIDebugCat_GP, GSIDebugType_Misc, GSIDebugLevel_HotError,
					"Tried to remove peer not in list.");
				return;
			}
		}
		pprev->pnext = peer->pnext;
	}

	// Check for pending messages.
	//////////////////////////////
	while(ArrayLength(peer->messages))
	{
		// Get the next message.
		////////////////////////
		message = (GPIMessage *)ArrayNth(peer->messages, 0);

		// Don't forward protocol messages.
		///////////////////////////////////
		if(message->type < 100)
			gpiSendServerBuddyMessage(connection, peer->profile, message->type, message->buffer.buffer + message->start);

		// Remove the message.
		//////////////////////
		ArrayDeleteAt(peer->messages, 0);
	}

	gpiDestroyPeer(connection, peer);
}
Beispiel #17
0
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// When a peer has accepted a GT2Connection the UDP layer needs to let 
// higher level app or message handler know that it accepted the request to
// to message a peer.
void gsUdpConnectedRoutingCB(GT2Connection theConnection, GT2Result theResult, GT2Byte *theMessage,
							 int theMessageLen)
{
	GSUdpEngineObject *aUdp = gsUdpEngineGetEngine();
	int aIndex, len;
	GSUdpErrorCode aCode;
	char anAddr[GS_IP_ADDR_AND_PORT];

	switch(theResult)
	{
		case GT2NegotiationError:
			aCode = GS_UDP_REMOTE_ERROR;
			break;
		case GT2Rejected:
			aCode = GS_UDP_REJECTED;
			break;
		case GT2TimedOut:
			aCode = GS_UDP_TIMED_OUT;
			break;
		case GT2Success:
			aCode = GS_UDP_NO_ERROR;
			break;
		default: 
			aCode = GS_UDP_UNKNOWN_ERROR;
			break;
	}
	if (theResult == GT2Rejected)
	{
		int aRemotePeerIdx;
		GSUdpRemotePeer aRemotePeer;
		aRemotePeer.mAddr = gt2GetRemoteIP(theConnection);
		aRemotePeer.mPort = gt2GetRemotePort(theConnection);
		aRemotePeerIdx = ArraySearch(aUdp->mRemotePeers, &aRemotePeer, gsUdpRemotePeerCompare, 0, 0);
		if (aRemotePeerIdx != NOT_FOUND)
		{
			gsDebugFormat(GSIDebugCat_Common, GSIDebugType_Network, GSIDebugLevel_Comment, 
				"[Udp Engine] Connect rejected by %s\n", gt2AddressToString(gt2GetRemoteIP(theConnection), 
				gt2GetRemotePort(theConnection), anAddr));

			ArrayDeleteAt(aUdp->mRemotePeers, aRemotePeerIdx);
		}
	}

	len = ArrayLength(aUdp->mMsgHandlers);
	for (aIndex = 0; aIndex < len; aIndex++)
	{
		int aRemotePeerIdx;
		GSUdpRemotePeer aRemotePeer;
		GSUdpMsgHandler *aTempHandler = (GSUdpMsgHandler *)ArrayNth(aUdp->mMsgHandlers, aIndex);
		
		aRemotePeer.mAddr = gt2GetRemoteIP(theConnection);
		aRemotePeer.mPort = gt2GetRemotePort(theConnection);
		aRemotePeerIdx = ArraySearch(aTempHandler->mPendingConnections, &aRemotePeer, gsUdpRemotePeerCompare, 0, 0);
		if (aRemotePeerIdx != NOT_FOUND)
		{
			if (aTempHandler->mConnected)
			{	
				gsDebugFormat(GSIDebugCat_Common, GSIDebugType_Network, GSIDebugLevel_Comment, 
					"[Udp Engine] Passing connect result to message handler\n");
				aTempHandler->mConnected(gt2GetRemoteIP(theConnection), gt2GetRemotePort(theConnection), 
					aCode, theResult == GT2Rejected ? gsi_true : gsi_false, aTempHandler->mUserData);				
			}
			ArrayDeleteAt(aTempHandler->mPendingConnections, aRemotePeerIdx);
			return;
		}
	}
	
	if (aUdp->mAppPendingConnections > 0)
	{
		if (aUdp->mAppConnected)
		{
			gsDebugFormat(GSIDebugCat_Common, GSIDebugType_Network, GSIDebugLevel_Comment, 
				"[Udp Engine] Passing connect result to app\n");
			aUdp->mAppConnected(gt2GetRemoteIP(theConnection),gt2GetRemotePort(theConnection), 
				aCode, theResult == GT2Rejected ? gsi_true : gsi_false, aUdp->mAppUserData);
		}
		aUdp->mAppPendingConnections--;
	}
	GSI_UNUSED(theMessage);
	GSI_UNUSED(theMessageLen);
	GSI_UNUSED(anAddr);
}