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; }
void gpiPeerMessageCallback(unsigned int ip, unsigned short port, unsigned char *message, unsigned int messageLength, gsi_bool reliable, void *userData) { GPConnection *connection = (GPConnection *)userData; GPIPeer *aPeer; unsigned char * buff; int writePos; int size; IN_ADDR anAddr; anAddr.s_addr = ip; aPeer = gpiGetPeerByAddr(connection, ip, port); if (!aPeer) { aPeer = gpiAddPeer(connection, -1, GPIFalse); if (aPeer) { aPeer->state = GPI_PEER_WAITING; aPeer->ip = ip; aPeer->port = port; } else { gsDebugFormat(GSIDebugCat_GP, GSIDebugType_Memory, GSIDebugLevel_HotError, "gpiPeerMessageCallback: out of memory when allocating peer, addr: %s:%d", inet_ntoa(anAddr), port); return; } } buff = (unsigned char *)aPeer->inputBuffer.buffer; writePos = aPeer->inputBuffer.len; size = aPeer->inputBuffer.size; // Check if the buffer needs to be resized. /////////////////////////////////////////// if((int)messageLength > (size - writePos)) { unsigned char *reallocedBuff; size = (writePos + max(GPI_READ_SIZE,(int)messageLength)); reallocedBuff = (unsigned char *)gsirealloc(buff, (unsigned int)size + 1); if(reallocedBuff == NULL) { gsDebugFormat(GSIDebugCat_GP, GSIDebugType_Memory, GSIDebugLevel_HotError, "gpiPeerMessageCallback: out of memory when reallocating buffer, addr: %s:%d", inet_ntoa(anAddr), port); gsifree(buff); gpiSetErrorString(connection, "Out of memory."); gpiCallErrorCallback(connection, GP_MEMORY_ERROR, GP_NON_FATAL); return; } else buff = reallocedBuff; } memcpy(&buff[writePos], message, messageLength); aPeer->inputBuffer.buffer = (char *)buff; aPeer->inputBuffer.len += messageLength; aPeer->inputBuffer.size = size; buff[aPeer->inputBuffer.len] = '\0'; GSI_UNUSED(reliable); GSI_UNUSED(anAddr); }