Example #1
0
void
gpiDestroyPeer(
  GPConnection * connection,
  GPIPeer * peer
)
{
#ifndef NOFILE
	// Cleanup any transfers that use this peer.
	////////////////////////////////////////////
	gpiTransferPeerDestroyed(connection, peer);
#endif

	//shutdown(peer->sock, 2);
	//closesocket(peer->sock);
	freeclear(peer->inputBuffer.buffer);
	freeclear(peer->outputBuffer.buffer);
	if(peer->messages)
	{
		ArrayFree(peer->messages);
		peer->messages = NULL;
	}
	freeclear(peer);
	
	GSI_UNUSED(connection);
}
Example #2
0
static GPIBool
gpiDisconnectCleanupProfile(
  GPConnection * connection,
  GPIProfile * profile,
  void * data
)
{
	GPIConnection * iconnection = (GPIConnection*)*connection;
	GSI_UNUSED(data);

    // Even if we cache buddy/block info, free it up to get rid of mem
    // leaks, just don't remove the profile until we save the cache.
    //////////////////////////////////////////////////////////////////
	if(profile->buddyStatus)
	{
        profile->buddyOrBlockCache = gsi_true;
        freeclear(profile->buddyStatus->statusString);
        freeclear(profile->buddyStatus->locationString);
        freeclear(profile->buddyStatus);	
	}
	if (profile->buddyStatusInfo)
	{
        profile->buddyOrBlockCache = gsi_true;
        freeclear(profile->buddyStatusInfo->richStatus);
        freeclear(profile->buddyStatusInfo->gameType);
        freeclear(profile->buddyStatusInfo->gameVariant);
        freeclear(profile->buddyStatusInfo->gameMapName);
        if (profile->buddyStatusInfo->extendedInfoKeys)
        {
            ArrayFree(profile->buddyStatusInfo->extendedInfoKeys);
            profile->buddyStatusInfo->extendedInfoKeys = NULL;
        }
        freeclear(profile->buddyStatusInfo);
	}
    if (profile->blocked)
        profile->buddyOrBlockCache = gsi_true;

	freeclear(profile->authSig);
	freeclear(profile->peerSig);
	profile->requestCount = 0;

	// Remove Profile if:
	//    (there is no info to cache) or
	//    (we only cache buddies/blocked and the user is not a buddy or a block)
	if ((!profile->cache) ||
		(iconnection->infoCachingBuddyAndBlockOnly==GPITrue && !profile->buddyOrBlockCache))
	{
		gpiRemoveProfile(connection, profile);
		return GPIFalse;
	}

	return GPITrue;
}
Example #3
0
GPResult gpiAuthBuddyRequest
( 
	GPConnection * connection,
	GPProfile profile
)
{
	GPIProfile * pProfile;
	GPIConnection * iconnection = (GPIConnection*)*connection;

	// Get the profile object.
	//////////////////////////
	if(!gpiGetProfile(connection, profile, &pProfile))
		Error(connection, GP_PARAMETER_ERROR, "Invalid profile.");

	// Check for a valid sig.
	/////////////////////////
	if(!pProfile->authSig)
		Error(connection, GP_PARAMETER_ERROR, "Invalid profile.");

	// Send the request.
	////////////////////
	CHECK_RESULT(gpiSendAuthBuddyRequest(connection, pProfile));

	// freeclear the sig if no more requests.
	////////////////////////////////////
	pProfile->requestCount--;
	if(!iconnection->infoCaching && (pProfile->requestCount <= 0))
	{
		freeclear(pProfile->authSig);
		if(gpiCanFreeProfile(pProfile))
			gpiRemoveProfile(connection, pProfile);
	}

	return GP_NO_ERROR;
}
Example #4
0
void
gpiDestroyOperation(
  GPConnection * connection,
  GPIOperation * operation
)
{
	GPIConnection * iconnection = (GPIConnection*)*connection;
	
	// Search?
	//////////
	if(operation->type == GPI_PROFILE_SEARCH)
	{
		GPISearchData * data = (GPISearchData *)operation->data;

		// One less.
		////////////
		iconnection->numSearches--;
		assert(iconnection->numSearches >= 0);

		// Close the socket.
		////////////////////
		shutdown(data->sock, 2);
		closesocket(data->sock);

		// freeclear the buffers.
		////////////////////
		freeclear(data->outputBuffer.buffer);
		freeclear(data->inputBuffer.buffer);
	}

	// freeclear the data.
	/////////////////
	freeclear(operation->data);

	// freeclear the operation struct.
	/////////////////////////////
	freeclear(operation);
}
Example #5
0
// gpiPeerRemoveOp:
// Assumes the list is NOT NULL otherwise it returns.
// Assumes the operation being passed in is on the queue.
// Assumes non-null inputs!
// Completed or Timed out Operations are deleted from queue by finding 
// the operation passed in.  Removal of operations don't necessarily 
// happen in order.
void gpiPeerRemoveOp(GPIPeer *peer, GPIPeerOp *operation)
{
	GS_ASSERT(peer);
	GS_ASSERT(operation);
	if (!peer || !operation)
	{
		gsDebugFormat(GSIDebugCat_GP, GSIDebugType_Misc, GSIDebugLevel_WarmError, "Peer operation not removed");
		return;
	}

	GS_ASSERT(peer->peerOpQueue.opList != NULL);
	if (peer->peerOpQueue.opList == NULL)
	{
		gsDebugFormat(GSIDebugCat_GP, GSIDebugType_Misc, GSIDebugLevel_WarmError, "Peer operation not removed");
		return;
	}

	if (peer->peerOpQueue.first == peer->peerOpQueue.last && peer->peerOpQueue.first == operation)
	{
		peer->peerOpQueue.opList = peer->peerOpQueue.first = peer->peerOpQueue.last = operation->next;
	}
	else if (peer->peerOpQueue.first == operation)
	{
		peer->peerOpQueue.first = peer->peerOpQueue.first->next;
		peer->peerOpQueue.opList = peer->peerOpQueue.first;
	}
	else
	{
		GPIPeerOp *aPrevOp = NULL;
		for(aPrevOp = peer->peerOpQueue.first ; aPrevOp->next != operation ; aPrevOp = aPrevOp->next)
		{
			if(aPrevOp->next == NULL)
			{
				// Can't find this peer in the list!
				////////////////////////////////////
				gsDebugFormat(GSIDebugCat_GP, GSIDebugType_Misc, GSIDebugLevel_HotError,
					"Tried to remove peer operation not in list.");
				return;
			}
		}
		aPrevOp->next = operation->next;
	}

	gsDebugFormat(GSIDebugCat_GP, GSIDebugType_Misc, GSIDebugLevel_Notice, "Peer operation removed");
	freeclear(operation);
}
Example #6
0
GPResult gpiBuddyHandleKeyRequest(GPConnection *connection, GPIPeer *peer)
{
	char *message;
	
	// get all the keys and put them in the message part of bm 
	//////////////////////////////////////////////////////////
	CHECK_RESULT(gpiSaveKeysToBuffer(connection, &message));
	
	// Done in case we haven't set any keys
	if (message == NULL)
		message = "";
	
	CHECK_RESULT(gpiSendBuddyMessage(connection, peer->profile, GPI_BM_KEYS_REPLY, message, GP_DONT_ROUTE, NULL));
	
	if (strcmp(message, "")!= 0)
		freeclear(message);
	return GP_NO_ERROR;
}
Example #7
0
GPResult
gpiRecvToBuffer(
  GPConnection * connection,
  SOCKET sock,
  GPIBuffer * inputBuffer,
  int * bytesRead,
  GPIBool * connClosed,
  char id[3]
)
{
	char * buffer;
	int len;
	int size;
	int rcode;
	int total;
	GPIBool closed;

	assert(sock != INVALID_SOCKET);
	assert(inputBuffer != NULL);
	assert(bytesRead != NULL);
	assert(connClosed != NULL);

	// Init locals.
	///////////////
	buffer = inputBuffer->buffer;
	len = inputBuffer->len;
	size = inputBuffer->size;
	total = 0;
	closed = GPIFalse;

	do
	{
		// Check if the buffer needs to be resized.
		///////////////////////////////////////////
		if((len + GPI_READ_SIZE) > size)
		{
			size = (len + GPI_READ_SIZE);
			buffer = (char *)gsirealloc(buffer, (unsigned int)size + 1);
			if(buffer == NULL)
				Error(connection, GP_MEMORY_ERROR, "Out of memory.");
		}

		// Read from the network.
		rcode = recv(sock, &buffer[len], size - len, 0);


		if(gsiSocketIsError(rcode))
		{
			int error = GOAGetLastError(sock);
			if((error != WSAEWOULDBLOCK) && (error != WSAEINPROGRESS) && (error != WSAETIMEDOUT) )
			{
				Error(connection, GP_NETWORK_ERROR, "There was an error reading from a socket.");
			}
		}
		else if(rcode == 0)
		{
			// Check for a closed connection.
			/////////////////////////////////
			closed = GPITrue;
			gsDebugFormat(GSIDebugCat_GP, GSIDebugType_Network, GSIDebugLevel_Comment,
				"RECVXXXX(%s): Connection closed\n", id);
		}
		else
		{
			#if defined(GPI_DUMP_NET_TRAFFIC) && defined(GSI_COMMON_DEBUG)
			{
				static int recvCount;
				char *buf = (char *)gsimalloc((size_t)(rcode + 1));
				memcpy(buf, &buffer[len], (size_t)rcode);
				buf[rcode] = '\0';
				gsDebugFormat(GSIDebugCat_GP, GSIDebugType_Network, GSIDebugLevel_RawDump,
					"RECV%04d(%s): %s\n", recvCount++, id, buf);
				freeclear(buf);
			}
			#elif defined(GSI_COMMON_DEBUG)
			{
				static int recvCount;
				gsDebugFormat(GSIDebugCat_GP, GSIDebugType_Network, GSIDebugLevel_RawDump,
					"RECV%04d(%s): %d\n", recvCount++, id, rcode);
			}
			#endif
			// Update the buffer len.
			/////////////////////////
			len += rcode;

			// Update the total.
			////////////////////
			total += rcode;
		}

		buffer[len] = '\0';
	}
	while((rcode >= 0) && !closed && (total < (128 * 1024)));

	if(total)
	{
		gsDebugFormat(GSIDebugCat_GP, GSIDebugType_Network, GSIDebugLevel_RawDump,
			"RECVTOTL(%s): %d\n", id, total);
	}
	
	// Set output stuff.
	////////////////////
	inputBuffer->buffer = buffer;
	inputBuffer->len = len;
	inputBuffer->size = size;
	*bytesRead = total;
	*connClosed = closed;

	GSI_UNUSED(id); //to get rid of codewarrior warnings

	return GP_NO_ERROR;
}
Example #8
0
static GPResult
gpiSendData(
  GPConnection * connection,
  SOCKET sock,
  const char * buffer,
  int bufferLen,
  GPIBool * closed,
  int * sent,
  char id[3]
)
{
	int rcode;

	rcode = send(sock, buffer, bufferLen, 0);
	if(gsiSocketIsError(rcode))
	{
		rcode = GOAGetLastError(sock);
		if((rcode != WSAEWOULDBLOCK) && (rcode != WSAEINPROGRESS) && (rcode != WSAETIMEDOUT) )
		{
			// handle peer connections specially
			if((id[0] == 'P') && (id[1] == 'R'))
				return GP_NETWORK_ERROR;
			CallbackError(connection, GP_NETWORK_ERROR, GP_NETWORK, "There was an error sending on a socket.");
		}

		*sent = 0;
		*closed = GPIFalse;
	}
	else if(rcode == 0)
	{
		gsDebugFormat(GSIDebugCat_GP, GSIDebugType_Network, GSIDebugLevel_Comment,
			"SENDXXXX(%s): Connection closed\n", id);

		*sent = 0;
		*closed = GPITrue;
	}
	else
	{
		#if defined(GPI_DUMP_NET_TRAFFIC) && defined(GSI_COMMON_DEBUG)
		{
			static int sendCount;
			char *buf = (char *)gsimalloc((size_t)(rcode + 1));
			memcpy(buf, buffer, (size_t)rcode);
			buf[rcode] = '\0';
			gsDebugFormat(GSIDebugCat_GP, GSIDebugType_Network, GSIDebugLevel_RawDump, "SENT%04d(%s): %s\n", sendCount++, id, buf);
			freeclear(buf);
		}
		#elif defined(GSI_COMMON_DEBUG)
		{
			static int sendCount;
			gsDebugFormat(GSIDebugCat_GP, GSIDebugType_Network, GSIDebugLevel_RawDump,
				"SENT%04d(%s): %d\n", sendCount++, id, rcode);
		}
		#endif

		*sent = rcode;
		*closed = GPIFalse;
	}

	return GP_NO_ERROR;
}
Example #9
0
void
gpiDisconnect(
  GPConnection * connection,
  GPIBool tellServer
)
{
	GPIConnection * iconnection = (GPIConnection*)*connection;
	GPIPeer * peer;
	GPIPeer * delPeer;
	GPIBool connClosed;

	// Check if we're already disconnected.
	// PANTS|05.15.00
	///////////////////////////////////////
	if(iconnection->connectState == GPI_DISCONNECTED)
		return;

	// Skip most of this stuff if we never actually connected.
	// PANTS|05.16.00
	//////////////////////////////////////////////////////////
	if(iconnection->connectState != GPI_NOT_CONNECTED)
	{
		// Are we connected?
		////////////////////
		if(tellServer && (iconnection->connectState == GPI_CONNECTED))
		{
			// Send the disconnect.
			///////////////////////
			gpiAppendStringToBuffer(connection, &iconnection->outputBuffer, "\\logout\\\\sesskey\\");
			gpiAppendIntToBuffer(connection, &iconnection->outputBuffer, iconnection->sessKey);
			gpiAppendStringToBuffer(connection, &iconnection->outputBuffer, "\\final\\");
		}

		// Always flush remaining messages.
		// PANTS|05.16.00
		///////////////////////////////////
		gpiSendFromBuffer(connection, iconnection->cmSocket, &iconnection->outputBuffer, &connClosed, GPITrue, "CM");

		// Cleanup the connection.
		//////////////////////////
		if(iconnection->cmSocket != INVALID_SOCKET)
		{
			shutdown(iconnection->cmSocket, 2);
			closesocket(iconnection->cmSocket);
			iconnection->cmSocket = INVALID_SOCKET;
		}
		
		if(/*iconnection->peerSocket != INVALID_SOCKET*/ gsUdpEngineIsInitialized())
		{
			//shutdown(iconnection->peerSocket, 2);
			//closesocket(iconnection->peerSocket);
			//iconnection->peerSocket = INVALID_SOCKET;
			gsUdpEngineRemoveMsgHandler(iconnection->mHeader);
			if (gsUdpEngineNoMoreMsgHandlers() && gsUdpEngineNoApp())
				gsUdpEngineShutdown();
		}

		// We're disconnected.
		//////////////////////
		iconnection->connectState = GPI_DISCONNECTED;

		// Don't keep the userid/profileid.
		///////////////////////////////////
		iconnection->userid = 0;
		iconnection->profileid = 0;
	}
	
	// freeclear all the memory.
	///////////////////////
	freeclear(iconnection->socketBuffer.buffer);
	freeclear(iconnection->inputBuffer);
	freeclear(iconnection->outputBuffer.buffer);
	freeclear(iconnection->updateproBuffer.buffer);
	freeclear(iconnection->updateuiBuffer.buffer);
	while(iconnection->operationList != NULL)
		gpiRemoveOperation(connection, iconnection->operationList);
	iconnection->operationList = NULL;
	for(peer = iconnection->peerList ; peer != NULL ; )
	{
		delPeer = peer;
		peer = peer->pnext;
		gpiDestroyPeer(connection, delPeer);
	}
	iconnection->peerList = NULL;
	
	// Cleanup buddies.
	// This is not optimal - because we can't continue the mapping
	// after freeing a profile, we need to start it all over again.
	///////////////////////////////////////////////////////////////
	while(!gpiProfileMap(connection, gpiDisconnectCleanupProfile, NULL))  { };
}
Example #10
0
// Freeing up transaction list darray
void gpiNpTransactionListFree(void *element)
{
    npIdLookupTrans *aTrans = (npIdLookupTrans *)element;
    freeclear(aTrans->npIdForAdd);
}
Example #11
0
GPResult
gpiDeleteBuddy(
  GPConnection * connection,
  GPProfile profile,
  GPIBool sendServerRequest
)
{
	GPIProfile * pProfile;
	GPIConnection * iconnection = (GPIConnection*)*connection;
	int index;

	// Get the profile object.
	//////////////////////////
	if(!gpiGetProfile(connection, profile, &pProfile))
		Error(connection, GP_PARAMETER_ERROR, "Invalid profile.");

	// Check that this is a buddy.
	//////////////////////////////
	// Removed - 092404 BED - User could be a buddy even though we don't have the status
	//if(!pProfile->buddyStatus)
	//	Error(connection, GP_PARAMETER_ERROR, "Profile not a buddy.");

	// Send the request.
	////////////////////
	if (GPITrue == sendServerRequest)
	{
		gpiAppendStringToBuffer(connection, &iconnection->outputBuffer, "\\delbuddy\\");
		gpiAppendStringToBuffer(connection, &iconnection->outputBuffer, "\\sesskey\\");
		gpiAppendIntToBuffer(connection, &iconnection->outputBuffer, iconnection->sessKey);
		gpiAppendStringToBuffer(connection, &iconnection->outputBuffer, "\\delprofileid\\");
		gpiAppendIntToBuffer(connection, &iconnection->outputBuffer, pProfile->profileId);
		gpiAppendStringToBuffer(connection, &iconnection->outputBuffer, "\\final\\");
	}

	// Need to fix up the buddy indexes.
	////////////////////////////////////
	if (pProfile->buddyStatus)
	{
		index = pProfile->buddyStatus->buddyIndex;
		assert(index >= 0);
		freeclear(pProfile->buddyStatus->statusString);
		freeclear(pProfile->buddyStatus->locationString);
		freeclear(pProfile->buddyStatus);
		if(gpiCanFreeProfile(pProfile))
			gpiRemoveProfile(connection, pProfile);
		iconnection->profileList.numBuddies--;
		assert(iconnection->profileList.numBuddies >= 0);
#ifndef _PS2
		gpiProfileMap(connection, gpiFixBuddyIndices, (void *)(unsigned long)index);
#else
		gpiProfileMap(connection, gpiFixBuddyIndices, (void *)index);
#endif
	}
	if (pProfile->buddyStatusInfo)
	{
		index = pProfile->buddyStatusInfo->buddyIndex;
		assert(index >= 0);
		freeclear(pProfile->buddyStatusInfo->richStatus);
		freeclear(pProfile->buddyStatusInfo->gameType);
		freeclear(pProfile->buddyStatusInfo->gameVariant);
		freeclear(pProfile->buddyStatusInfo->gameMapName);
		freeclear(pProfile->buddyStatusInfo);
		if (pProfile->buddyStatusInfo->extendedInfoKeys)
		{
			ArrayFree(pProfile->buddyStatusInfo->extendedInfoKeys);
			pProfile->buddyStatusInfo->extendedInfoKeys = NULL;
		}

		if(gpiCanFreeProfile(pProfile))
			gpiRemoveProfile(connection, pProfile);
		iconnection->profileList.numBuddies--;
		assert(iconnection->profileList.numBuddies >= 0);
#ifndef _PS2
		gpiProfileMap(connection, gpiFixBuddyIndices, (void *)(unsigned long)index);
#else
		gpiProfileMap(connection, gpiFixBuddyIndices, (void *)index);
#endif
	}
	return GP_NO_ERROR;
}
Example #12
0
GPResult
gpiProcessRecvBuddyMessage(
  GPConnection * connection,
  const char * input
)
{
	char buffer[4096];
	int type;
	int profileid;
	time_t date;
	GPICallback callback;
	GPIProfile * profile;
	GPIBuddyStatus * buddyStatus;
	char intValue[16];
	char * str;
	unsigned short port;
	int productID;
	GPIConnection * iconnection = (GPIConnection*)*connection;
	char strTemp[max(GP_STATUS_STRING_LEN, GP_LOCATION_STRING_LEN)];

	// Check the type of bm.
	////////////////////////
	if(!gpiValueForKey(input, "\\bm\\", buffer, sizeof(buffer)))
		CallbackFatalError(connection, GP_NETWORK_ERROR, GP_PARSE, "Unexpected data was received from the server.");
	type = atoi(buffer);

	// Get the profile this is from.
	////////////////////////////////
	if(!gpiValueForKey(input, "\\f\\", buffer, sizeof(buffer)))
		CallbackFatalError(connection, GP_NETWORK_ERROR, GP_PARSE, "Unexpected data was received from the server.");
	profileid = atoi(buffer);

	// Get the time.
	////////////////
	if(!gpiValueForKey(input, "\\date\\", buffer, sizeof(buffer)))
		date = time(NULL);
	else
		date = atoi(buffer);

	// What type of message is this?
	////////////////////////////////
	switch(type)
	{
	case GPI_BM_MESSAGE:
		// Call the callback.
		/////////////////////
		callback = iconnection->callbacks[GPI_RECV_BUDDY_MESSAGE];
		if(callback.callback != NULL)
		{
			GPRecvBuddyMessageArg * arg;
			arg = (GPRecvBuddyMessageArg *)gsimalloc(sizeof(GPRecvBuddyMessageArg));
			if(arg == NULL)
				Error(connection, GP_MEMORY_ERROR, "Out of memory.");

			if(!gpiValueForKey(input, "\\msg\\", buffer, sizeof(buffer)))
				CallbackFatalError(connection, GP_NETWORK_ERROR, GP_PARSE, "Unexpected data was received from the server.");
#ifndef GSI_UNICODE
			arg->message = (char *)gsimalloc(strlen(buffer) + 1);
			if(arg->message == NULL)
				Error(connection, GP_MEMORY_ERROR, "Out of memory.");
			strcpy(arg->message, buffer);
			arg->profile = (GPProfile)profileid;
			arg->date = (unsigned int)date;
#else
			arg->message = (unsigned short*)gsimalloc(strlen(buffer)*2+2);
			if(arg->message == NULL)
				Error(connection, GP_MEMORY_ERROR, "Out of memory.");
			UTF8ToUCS2String(buffer, arg->message);
			arg->profile = (GPProfile)profileid;
			arg->date = (unsigned int)date;
#endif
			CHECK_RESULT(gpiAddCallback(connection, callback, arg, NULL, GPI_ADD_MESSAGE));
		}
		break;
	case GPI_BM_UTM:
		// Call the callback.
		/////////////////////
		callback = iconnection->callbacks[GPI_RECV_BUDDY_UTM];
		if(callback.callback != NULL)
		{
			GPRecvBuddyUTMArg * arg;
			arg = (GPRecvBuddyUTMArg *)gsimalloc(sizeof(GPRecvBuddyUTMArg));
			if(arg == NULL)
				Error(connection, GP_MEMORY_ERROR, "Out of memory.");

			if(!gpiValueForKey(input, "\\msg\\", buffer, sizeof(buffer)))
				CallbackFatalError(connection, GP_NETWORK_ERROR, GP_PARSE, "Unexpected data was received from the server.");
#ifndef GSI_UNICODE
			arg->message = (char *)gsimalloc(strlen(buffer) + 1);
			if(arg->message == NULL)
				Error(connection, GP_MEMORY_ERROR, "Out of memory.");
			strcpy(arg->message, buffer);
			arg->profile = (GPProfile)profileid;
			arg->date = (unsigned int)date;
#else
			arg->message = (unsigned short*)gsimalloc(strlen(buffer)*2+2);
			if(arg->message == NULL)
				Error(connection, GP_MEMORY_ERROR, "Out of memory.");
			UTF8ToUCS2String(buffer, arg->message);
			arg->profile = (GPProfile)profileid;
			arg->date = (unsigned int)date;
#endif
			CHECK_RESULT(gpiAddCallback(connection, callback, arg, NULL, GPI_ADD_BUDDYUTM));
		}
		break;

	case GPI_BM_REQUEST:
		// Get the profile, adding if needed.
		/////////////////////////////////////
		profile = gpiProfileListAdd(connection, profileid);
		if(!profile)
			Error(connection, GP_MEMORY_ERROR, "Out of memory.");

		// Get the reason.
		//////////////////
		if(!gpiValueForKey(input, "\\msg\\", buffer, sizeof(buffer)))
			CallbackFatalError(connection, GP_NETWORK_ERROR, GP_PARSE, "Unexpected data was received from the server.");

		// Find where the sig starts.
		/////////////////////////////
		str = strstr(buffer, "|signed|");
		if(str == NULL)
			CallbackFatalError(connection, GP_NETWORK_ERROR, GP_PARSE, "Unexpected data was received from the server.");

		// Get the sig out of the message.
		//////////////////////////////////
		*str = '\0';
		str += 8;
		if(strlen(str) != 32)
			CallbackFatalError(connection, GP_NETWORK_ERROR, GP_PARSE, "Unexpected data was received from the server.");
		freeclear(profile->authSig);
		profile->authSig = goastrdup(str);
		profile->requestCount++;

		// Call the callback.
		/////////////////////
		callback = iconnection->callbacks[GPI_RECV_BUDDY_REQUEST];
		if(callback.callback != NULL)
		{
			GPRecvBuddyRequestArg * arg;
			arg = (GPRecvBuddyRequestArg *)gsimalloc(sizeof(GPRecvBuddyRequestArg));
			if(arg == NULL)
				Error(connection, GP_MEMORY_ERROR, "Out of memory.");
#ifndef GSI_UNICODE
			strzcpy(arg->reason, buffer, GP_REASON_LEN);
#else
			UTF8ToUCS2String(buffer, arg->reason);
#endif
			arg->profile = (GPProfile)profileid;
			arg->date = (unsigned int)date;

			CHECK_RESULT(gpiAddCallback(connection, callback, arg, NULL, GPI_ADD_BUDDDYREQUEST));
		}
		break;

	case GPI_BM_AUTH:
		// call the callback
		callback = iconnection->callbacks[GPI_RECV_BUDDY_AUTH];
		if(callback.callback != NULL)
		{
			GPRecvBuddyAuthArg * arg;
			arg = (GPRecvBuddyAuthArg *)gsimalloc(sizeof(GPRecvBuddyAuthArg));

			if (arg == NULL)
				Error(connection, GP_MEMORY_ERROR, "Out of memory.");
			arg->profile = (GPProfile)profileid;
			arg->date = (unsigned int)date;
			CHECK_RESULT(gpiAddCallback(connection, callback, arg, NULL, GPI_ADD_BUDDYAUTH));
		}
		break;

	case GPI_BM_REVOKE:
		// call the callback
		callback = iconnection->callbacks[GPI_RECV_BUDDY_REVOKE];
		if(callback.callback != NULL)
		{
			GPRecvBuddyRevokeArg * arg;
			arg = (GPRecvBuddyRevokeArg *)gsimalloc(sizeof(GPRecvBuddyRevokeArg));

			if (arg == NULL)
				Error(connection, GP_MEMORY_ERROR, "Out of memory.");
			arg->profile = (GPProfile)profileid;
			arg->date = (unsigned int)date;

			CHECK_RESULT(gpiAddCallback(connection, callback, arg, NULL, GPI_ADD_BUDDYREVOKE));
		}
		break;
		

	case GPI_BM_STATUS:
		// Get the profile, adding if needed.
		/////////////////////////////////////
		profile = gpiProfileListAdd(connection, profileid);
		if(!profile)
			Error(connection, GP_MEMORY_ERROR, "Out of memory.");

        // Make sure profile wasn't blocked prior to getting the status update
        //////////////////////////////////////////////////////////////////////
        if (!profile->blocked)
        {
		    // This is a buddy.
		    ///////////////////
		    if(!profile->buddyStatus)
		    {
			    profile->buddyStatus = (GPIBuddyStatus *)gsimalloc(sizeof(GPIBuddyStatus));
			    if(!profile->buddyStatus)
				    Error(connection, GP_MEMORY_ERROR, "Out of memory.");
			    memset(profile->buddyStatus, 0, sizeof(GPIBuddyStatus));
			    if (profile->buddyStatusInfo)
			    {
				    profile->buddyStatus->buddyIndex = profile->buddyStatusInfo->buddyIndex;
				    gpiRemoveBuddyStatusInfo(profile->buddyStatusInfo);
				    profile->buddyStatusInfo = NULL;
			    }
			    else
				    profile->buddyStatus->buddyIndex = iconnection->profileList.numBuddies++;
		    }

		    // Get the buddy status.
		    ////////////////////////
		    buddyStatus = profile->buddyStatus;

		    // Get the msg.
		    ///////////////
		    if(!gpiValueForKey(input, "\\msg\\", buffer, sizeof(buffer)))
			    CallbackFatalError(connection, GP_NETWORK_ERROR, GP_PARSE, "Unexpected data was received from the server.");

		    // Get the status.
		    //////////////////
		    if(!gpiValueForKey(buffer, "|s|", intValue, sizeof(intValue)))
		    {
			    CallbackFatalError(connection, GP_NETWORK_ERROR, GP_PARSE, "Unexpected data was received from the server.");
		    }
		    else
		    {
			    buddyStatus->status = (GPEnum)atoi(intValue);
		    }
		    // Get the status string.
		    /////////////////////////
		    freeclear(buddyStatus->statusString);
		    if(!gpiValueForKey(buffer, "|ss|", strTemp, GP_STATUS_STRING_LEN))
			    strTemp[0] = '\0';
		    buddyStatus->statusString = goastrdup(strTemp);
		    if(!buddyStatus->statusString)
			    Error(connection, GP_MEMORY_ERROR, "Out of memory.");

		    // Get the location string.
		    ///////////////////////////
		    freeclear(buddyStatus->locationString);
		    if(!gpiValueForKey(buffer, "|ls|", strTemp, GP_LOCATION_STRING_LEN))
			    strTemp[0] = '\0';
		    buddyStatus->locationString = goastrdup(strTemp);
		    if(!buddyStatus->locationString)
			    Error(connection, GP_MEMORY_ERROR, "Out of memory.");

		    // Get the ip.
		    //////////////
		    if(!gpiValueForKey(buffer, "|ip|", intValue, sizeof(intValue)))
			    buddyStatus->ip = 0;
		    else
			    buddyStatus->ip = htonl((unsigned int)atoi(intValue));

		    // Get the port.
		    ////////////////
		    if(!gpiValueForKey(buffer, "|p|", intValue, sizeof(intValue)))
			    buddyStatus->port = 0;
		    else
		    {
			    port = (unsigned short)atoi(intValue);
			    buddyStatus->port = htons(port);
		    }

		    // Get the quiet mode flags.
		    ////////////////////////////
		    if(!gpiValueForKey(buffer, "|qm|", intValue, sizeof(intValue)))
			    buddyStatus->quietModeFlags = GP_SILENCE_NONE;
		    else
			    buddyStatus->quietModeFlags = (GPEnum)atoi(intValue);

		    // Call the callback.
		    /////////////////////
		    callback = iconnection->callbacks[GPI_RECV_BUDDY_STATUS];
		    if(callback.callback != NULL)		
		    {
			    GPRecvBuddyStatusArg * arg;
			    arg = (GPRecvBuddyStatusArg *)gsimalloc(sizeof(GPRecvBuddyStatusArg));
			    if(arg == NULL)
				    Error(connection, GP_MEMORY_ERROR, "Out of memory.");

			    arg->profile = (GPProfile)profileid;
			    arg->index = buddyStatus->buddyIndex;
			    arg->date = (unsigned int)date;

			    CHECK_RESULT(gpiAddCallback(connection, callback, arg, NULL, GPI_ADD_STATUS));
		    }
        }
		break;

	case GPI_BM_INVITE:
		// Get the msg.
		///////////////
		if(!gpiValueForKey(input, "\\msg\\", buffer, sizeof(buffer)))
			CallbackFatalError(connection, GP_NETWORK_ERROR, GP_PARSE, "Unexpected data was received from the server.");

		// Find the productid.
		//////////////////////
		str = strstr(buffer, "|p|");
		if(str == NULL)
			CallbackFatalError(connection, GP_NETWORK_ERROR, GP_PARSE, "Unexpected data was received from the server.");

		// Skip the |p|.
		////////////////
		str += 3;
		if(str[0] == '\0')
			CallbackFatalError(connection, GP_NETWORK_ERROR, GP_PARSE, "Unexpected data was received from the server.");

		// Get the productid.
		/////////////////////
		productID = atoi(str);

		// Find the location string (optional - older versions won't have)
		str = strstr(buffer, "|l|");
		if(str != NULL)
			strzcpy(strTemp, (str+3), sizeof(strTemp));
		else
			strTemp[0] = '\0'; // no location, set to empty string
		
		// Call the callback.
		/////////////////////
		callback = iconnection->callbacks[GPI_RECV_GAME_INVITE];
		if(callback.callback != NULL)
		{
			GPRecvGameInviteArg * arg;
			arg = (GPRecvGameInviteArg *)gsimalloc(sizeof(GPRecvGameInviteArg));
			if(arg == NULL)
				Error(connection, GP_MEMORY_ERROR, "Out of memory.");

			arg->profile = (GPProfile)profileid;
			arg->productID = productID;
#ifdef GSI_UNICODE
			AsciiToUCS2String(strTemp, arg->location);
#else
			strcpy(arg->location, strTemp);
#endif

			CHECK_RESULT(gpiAddCallback(connection, callback, arg, NULL, 0));
		}
		break;

	case GPI_BM_PING:
		// Get the msg.
		///////////////
		if(!gpiValueForKey(input, "\\msg\\", buffer, sizeof(buffer)))
			CallbackFatalError(connection, GP_NETWORK_ERROR, GP_PARSE, "Unexpected data was received from the server.");

		// Send back a pong.
		////////////////////
		gpiSendBuddyMessage(connection, profileid, GPI_BM_PONG, "1", 0, NULL);

		break;

#ifndef NOFILE
	case GPI_BM_PONG:
		// Lets the transfers handle this.
		//////////////////////////////////
		gpiTransfersHandlePong(connection, profileid, NULL);

		break;
#endif
	}

	return GP_NO_ERROR;
}
Example #13
0
GPResult gpiProcessRecvBuddyStatusInfo(GPConnection *connection, const char *input)
{
	char buffer[1024];
	int profileid;
	time_t date;
	GPICallback callback;
	GPIProfile * profile;
	GPIBuddyStatusInfo * buddyStatusInfo;
	GPIConnection * iconnection = (GPIConnection*)*connection;

	// This is what the message should look like.  Its broken up for easy viewing.
	//
	// "\bsi\\state\\profile\\bip\\bport\\hostip\\hprivip\"
	// "\qport\\hport\\sessflags\\rstatus\\gameType\"
	// "\gameVnt\\gameMn\\product\\qmodeflags\"
	////////////////////////////////
	date = time(NULL);
	// Get the buddy's profile
	////////////////////////////////
	if(!gpiValueForKey(input, "\\profile\\", buffer, sizeof(buffer)))
		CallbackFatalError(connection, GP_NETWORK_ERROR, GP_PARSE, "Unexpected data was received from the server.");
	profileid = atoi(buffer);

	// Get the profile from the SDK's list, adding it if needed.
	/////////////////////////////////////
	profile = gpiProfileListAdd(connection, profileid);
	if(!profile)
		Error(connection, GP_MEMORY_ERROR, "Out of memory.");

    // Make sure profile wasn't blocked prior to getting the status update
    //////////////////////////////////////////////////////////////////////
    if (!profile->blocked)
    {
	    // This is a buddy.
	    ///////////////////
	    if(!profile->buddyStatusInfo)
	    {
		    profile->buddyStatusInfo = (GPIBuddyStatusInfo *)gsimalloc(sizeof(GPIBuddyStatusInfo));
		    if(!profile->buddyStatusInfo)
			    Error(connection, GP_MEMORY_ERROR, "Out of memory.");
		    memset(profile->buddyStatusInfo, 0, sizeof(GPIBuddyStatusInfo));
		    if (profile->buddyStatus)
		    {
			    profile->buddyStatusInfo->buddyIndex = profile->buddyStatus->buddyIndex;
			    gpiRemoveBuddyStatus(profile->buddyStatus);
			    profile->buddyStatus = NULL;
		    }
		    else
			    profile->buddyStatusInfo->buddyIndex = iconnection->profileList.numBuddies++;
		    profile->buddyStatusInfo->extendedInfoKeys = ArrayNew(sizeof(GPIKey), GPI_INITIAL_NUM_KEYS, gpiStatusInfoKeyFree);
		    if (!profile->buddyStatusInfo->extendedInfoKeys)
			    Error(connection, GP_MEMORY_ERROR, "Out of memory.");
	    }

	    // extract the buddy status information and 
	    // fill in appropriate information.
	    /////////////////////////////////////////////
	    buddyStatusInfo = profile->buddyStatusInfo;
    	
	    if (!gpiValueForKey(input, "\\state\\", buffer, sizeof(buffer)))
		    CallbackFatalError(connection, GP_NETWORK_ERROR, GP_PARSE, "Unexpected data was received from the server.");
	    buddyStatusInfo->statusState = (GPEnum)atoi(buffer);

	    if (!gpiValueForKey(input, "\\bip\\", buffer, sizeof(buffer)))
		    CallbackFatalError(connection, GP_NETWORK_ERROR, GP_PARSE, "Unexpected data was received from the server.");
	    buddyStatusInfo->buddyIp = htonl((unsigned int)atoi(buffer));
    	
	    if (!gpiValueForKey(input, "\\bport\\", buffer, sizeof(buffer)))
		    CallbackFatalError(connection, GP_NETWORK_ERROR, GP_PARSE, "Unexpected data was received from the server.");
	    buddyStatusInfo->buddyPort = (unsigned short)atoi(buffer);
    	
	    if (!gpiValueForKey(input, "\\hostip\\", buffer, sizeof(buffer)))
		    CallbackFatalError(connection, GP_NETWORK_ERROR, GP_PARSE, "Unexpected data was received from the server.");
	    buddyStatusInfo->hostIp = htonl((unsigned int)atoi(buffer));

	    if (!gpiValueForKey(input, "\\hprivip\\", buffer, sizeof(buffer)))
		    CallbackFatalError(connection, GP_NETWORK_ERROR, GP_PARSE, "Unexpected data was received from the server.");
	    buddyStatusInfo->hostPrivateIp = htonl((unsigned int)atoi(buffer));

	    if (!gpiValueForKey(input, "\\qport\\", buffer, sizeof(buffer)))
		    CallbackFatalError(connection, GP_NETWORK_ERROR, GP_PARSE, "Unexpected data was received from the server.");
	    buddyStatusInfo->queryPort = (unsigned short)atoi(buffer);

	    if (!gpiValueForKey(input, "\\hport\\", buffer, sizeof(buffer)))
		    CallbackFatalError(connection, GP_NETWORK_ERROR, GP_PARSE, "Unexpected data was received from the server.");
	    buddyStatusInfo->hostPort = (unsigned short)atoi(buffer);
    	
	    if (!gpiValueForKey(input, "\\sessflags\\", buffer, sizeof(buffer)))
		    CallbackFatalError(connection, GP_NETWORK_ERROR, GP_PARSE, "Unexpected data was received from the server.");
	    buddyStatusInfo->sessionFlags = (unsigned int)atoi(buffer);

	    freeclear(buddyStatusInfo->richStatus);
	    if (!gpiValueForKey(input, "\\rstatus\\", buffer, sizeof(buffer)))
		    CallbackFatalError(connection, GP_NETWORK_ERROR, GP_PARSE, "Unexpected data was received from the server.");
	    buddyStatusInfo->richStatus = goastrdup(buffer);
    	
	    freeclear(buddyStatusInfo->gameType);
	    if (!gpiValueForKey(input, "\\gameType\\", buffer, sizeof(buffer)))
		    CallbackFatalError(connection, GP_NETWORK_ERROR, GP_PARSE, "Unexpected data was received from the server.");
	    buddyStatusInfo->gameType = goastrdup(buffer);

	    freeclear(buddyStatusInfo->gameVariant);
	    if (!gpiValueForKey(input, "\\gameVnt\\", buffer, sizeof(buffer)))
		    CallbackFatalError(connection, GP_NETWORK_ERROR, GP_PARSE, "Unexpected data was received from the server.");
	    buddyStatusInfo->gameVariant = goastrdup(buffer);

	    freeclear(buddyStatusInfo->gameMapName);
	    if (!gpiValueForKey(input, "\\gameMn\\", buffer, sizeof(buffer)))
		    CallbackFatalError(connection, GP_NETWORK_ERROR, GP_PARSE, "Unexpected data was received from the server.");
	    buddyStatusInfo->gameMapName = goastrdup(buffer);

	    if (!gpiValueForKey(input, "\\product\\", buffer, sizeof(buffer)))
		    CallbackFatalError(connection, GP_NETWORK_ERROR, GP_PARSE, "Unexpected data was received from the server.");
	    buddyStatusInfo->productId = (int)atoi(buffer);

	    if (!gpiValueForKey(input, "\\qmodeflags\\", buffer, sizeof(buffer)))
		    CallbackFatalError(connection, GP_NETWORK_ERROR, GP_PARSE, "Unexpected data was received from the server.");
	    buddyStatusInfo->quietModeFlags = (GPEnum)atoi(buffer);
    	
	    callback = iconnection->callbacks[GPI_RECV_BUDDY_STATUS];
	    if (callback.callback != NULL)
	    {
		    GPRecvBuddyStatusArg *anArg;
		    anArg = (GPRecvBuddyStatusArg *)gsimalloc(sizeof(GPRecvBuddyStatusArg));
		    if (anArg == NULL)
			    Error(connection, GP_MEMORY_ERROR, "Out of memory.");

		    anArg->date = (unsigned int)date;
		    anArg->index = buddyStatusInfo->buddyIndex;
		    anArg->profile = profileid;

		    CHECK_RESULT(gpiAddCallback(connection, callback, anArg, NULL, 0));
	    }
    }
	return GP_NO_ERROR;
	
}
Example #14
0
static void gpiFreeMessage(void * elem)
{
	GPIMessage * message = (GPIMessage *)elem;

	freeclear(message->buffer.buffer);
}
Example #15
0
//FUNCTIONS
///////////
static GPResult
gpiProcessPeerInitiatingConnection(
  GPConnection * connection,
  GPIPeer * peer
)
{
	GPIConnection * iconnection = (GPIConnection*)*connection;
	//int state;
	char * str = NULL;
	//int len;
	GPIBool connClosed;
	GPIProfile * pProfile;
	GPResult result;
	GSUdpPeerState aPeerState;
	
	GS_ASSERT(peer);
	if (!peer)
		return GP_NETWORK_ERROR;

	GS_ASSERT(peer->state != GPI_PEER_DISCONNECTED && peer->state != GPI_PEER_NOT_CONNECTED);
	if (peer->state == GPI_PEER_DISCONNECTED || peer->state == GPI_PEER_NOT_CONNECTED)
		return GP_NETWORK_ERROR;
	// Check the state.
	///////////////////
	switch(peer->state)
	{
		case GPI_PEER_GETTING_SIG:
			// Do nothing - we're waiting for getinfo to get the sig.
			/////////////////////////////////////////////////////////
			break;

		case GPI_PEER_GOT_SIG:
		{
			// Start the connect.
			/////////////////////
			gsDebugFormat(GSIDebugCat_GP, GSIDebugType_State, GSIDebugLevel_Verbose, "Got the peer signature for profileid: %d\n", peer->profile);
			CHECK_RESULT(gpiPeerStartConnect(connection, peer));

			break;
		}
		case GPI_PEER_CONNECTING:
		{	
			// Check if the connect finished.
			/////////////////////////////////
			/*
			CHECK_RESULT(gpiCheckSocketConnect(connection, peer->sock, &state));
			if(state == GPI_DISCONNECTED)
			{
				Error(connection, GP_NETWORK_ERROR, "Error connecting to a peer.");
			}
			*/

			gsUdpEngineGetPeerState(peer->ip, peer->port, &aPeerState);

			if(aPeerState == GS_UDP_PEER_CONNECTED)
			{
				GPIPeer * pcurr;
				GPIBool freePeerSig = GPITrue;

				// Get the profile object.
				//////////////////////////
				if(!gpiGetProfile(connection, peer->profile, &pProfile))
					Error(connection, GP_NETWORK_ERROR, "Error connecting to a peer.");

				// Send the auth.
				/////////////////
				gpiAppendStringToBuffer(connection, &peer->outputBuffer, "\\auth\\");
				gpiAppendStringToBuffer(connection, &peer->outputBuffer, "\\pid\\");
				gpiAppendIntToBuffer(connection, &peer->outputBuffer, iconnection->profileid);
				gpiAppendStringToBuffer(connection, &peer->outputBuffer, "\\nick\\");
				gpiAppendStringToBuffer(connection, &peer->outputBuffer, iconnection->nick);
				gpiAppendStringToBuffer(connection, &peer->outputBuffer, "\\sig\\");
				gpiAppendStringToBuffer(connection, &peer->outputBuffer, pProfile->peerSig);
				gpiAppendStringToBuffer(connection, &peer->outputBuffer, "\\final\\");

				// Are there any other peers still connecting?
				//////////////////////////////////////////////
				for(pcurr = iconnection->peerList ; pcurr != NULL ; pcurr = pcurr->pnext)
					if((pcurr->profile == peer->profile) && (pcurr != peer))
						if(pcurr->state <= GPI_PEER_CONNECTING)
							freePeerSig = GPIFalse;

				// freeclear it?
				///////////
				if(freePeerSig)
				{
					freeclear(pProfile->peerSig);
					if(gpiCanFreeProfile(pProfile))
						gpiRemoveProfile(connection, pProfile);
				}

				// Update the state.
				////////////////////
				peer->state = GPI_PEER_WAITING;
			}
			
			break;
		}
		case GPI_PEER_WAITING:
		{
			// Check for a response.
			////////////////////////
			//CHECK_RESULT(gpiRecvToBuffer(connection, peer->sock, &peer->inputBuffer, &len, &connClosed, "PR"));

			// Check for a final.
			/////////////////////
			if (peer->inputBuffer.buffer)
				str = strstr(peer->inputBuffer.buffer, "\\final\\");
			if(str != NULL)
			{
				str[0] = '\0';
				str += 7;

				// Was it rejected?
				///////////////////
				if(strncmp(peer->inputBuffer.buffer, "\\anack\\", 7) == 0)
				{
					// Rejected.
					////////////
					peer->nackCount++;

					// Is this more than once?
					//////////////////////////
					if(peer->nackCount > 1)
					{
						// we shouldn't reach this case unless there is a problem with 
						// the server when getting a buddy's signature

						// Give up already.
						///////////////////
						Error(connection, GP_NETWORK_ERROR, "Error getting buddy authorization.");
					}

					// Try getting the latest sig.
					//////////////////////////////
					CHECK_RESULT(gpiPeerGetSig(connection, peer));
				}
				else if(strncmp(peer->inputBuffer.buffer, "\\aack\\", 6) != 0)
				{
					// Unknown message.
					///////////////////
					Error(connection, GP_NETWORK_ERROR, "Error parsing buddy message.");
				}

				// The connection has been established.
				///////////////////////////////////////
				peer->state = GPI_PEER_CONNECTED;
				peer->inputBuffer.len = 0;
			}

			break;
		}
		// code should not reach here.
		default: break;
	}

	// Send stuff that needs to be sent.
	////////////////////////////////////
	if(peer->outputBuffer.len > 0)
	{
		//result = gpiSendFromBuffer(connection, peer->sock, &peer->outputBuffer, &connClosed, GPITrue, "PR");
		result = gpiSendBufferToPeer(connection, peer->ip, peer->port, &peer->outputBuffer, &connClosed, GPITrue);
		if(connClosed || (result != GP_NO_ERROR))
			peer->state = GPI_PEER_DISCONNECTED;
	}
	
	return GP_NO_ERROR;
}