Beispiel #1
0
GPResult
gpiSendBuddyMessage(
  GPConnection * connection,
  int profileid,
  int type,
  const char * message,
  int sendOption,
  GPIPeerOp *peerOp
)
{
	GPIPeer * peer;
	GPIProfile * profile;
	//GPIConnection *iconnection = (GPIConnection *)*connection;
	peer = gpiGetPeerByProfile(connection, profileid);
	if(!peer)
	{
		// Check if we should send this through the server.
		////////////////////////////////////////////////////
		if(!gpiGetProfile(connection, profileid, &profile) ||
		   (!profile->buddyStatusInfo || !profile->buddyStatusInfo->buddyPort))
		{
			if (sendOption == GP_DONT_ROUTE)
				return GP_NETWORK_ERROR;
			return gpiSendServerBuddyMessage(connection, profileid, type, message);
		}

		// Create a new peer connection for this message.
		/////////////////////////////////////////////////
		peer = gpiAddPeer(connection, profileid, GPITrue);
		if(!peer)
			return GP_MEMORY_ERROR;

		// Check if we need a sig.
		//////////////////////////
		if(!profile->peerSig)
		{
			// Get the sig.
			///////////////
			CHECK_RESULT(gpiPeerGetSig(connection, peer));
		}
		else
		{
			// Try to connect to the peer.
			//////////////////////////////
			CHECK_RESULT(gpiPeerStartConnect(connection, peer));
		}
	}
	else if (peer->state == GPI_PEER_DISCONNECTED)
	{
		if (gpiGetProfile(connection, profileid, &profile))
		{
			// clear the buddy port to prevent future messages from 
			// being sent via UDP layer
			if (profile->buddyStatusInfo)
				profile->buddyStatusInfo->buddyPort = 0;

			// send the message through the server
			if (sendOption == GP_DONT_ROUTE)
				return GP_NETWORK_ERROR;
			if (type < 100)
				return gpiSendServerBuddyMessage(connection, profileid, type, message);
		}
	}
	
	if (peerOp)
	{
		gpiPeerAddOp(peer, peerOp);
	}
	// Copy the message.
	////////////////////
	CHECK_RESULT(gpiPeerAddMessage(connection, peer, type, message));

	return GP_NO_ERROR;
}
Beispiel #2
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;
}