void ReadReadyHandler_MsgServer(AsyncCommBuffer buffer)
{
	int					res				= FUNC_RETURN_OK;
	ConnectionTrack 	newtrack 		= NULL;
	ConnectionTrackData tmptrackdata;
	AsyncCommBuffer     newcommbuffer   = NULL;
	struct sockaddr_in	clientaddr;
	socklen_t			clientaddrlen	= sizeof(clientaddr);
	int					fd				= -1;

	/* Always accept the connection. */
	fd = accept(buffer->FD, (struct sockaddr *)&clientaddr, &clientaddrlen);
	if ( fd == -1 )
	{
		elog(WARNING, "Resource manager socket accept error is detected. errno %d",
					  errno);
		return;
	}

	/* Create AsyncComm Message handler instance. */
	AsyncCommMessageHandlerContext context = createConnTrackHandlerContext();

	/* Add new client fd into AsyncComm manager. */
	res = registerFileDesc(fd,
						   ASYNCCOMM_READBYTES | ASYNCCOMM_WRITEBYTES,
						   &AsyncCommBufferHandlersMessage,
						   context,
						   &newcommbuffer);
	if ( res != FUNC_RETURN_OK )
	{
		Assert(newcommbuffer == NULL);
		/* close the connection and cleanup. */
		closeConnectionRemote(&fd);
		rm_pfree(AsyncCommContext, context);
		return;
	}

	assignFileDescClientAddressInfo(newcommbuffer,
									NULL,
									0,
									&clientaddr,
									clientaddrlen);

	/* Let context able to track comm buffer. */
	context->AsyncBuffer = newcommbuffer;

	/* Call callback function to initialize context for message handlers. */
	InitHandler_Message(newcommbuffer);

	elog(DEBUG3, "Resource manager accepted one client connected from "
				 "%s:%d as FD %d.\n",
				 newcommbuffer->ClientAddrDotStr,
				 newcommbuffer->ClientAddrPort,
				 newcommbuffer->FD);
}
示例#2
0
/*
 * A wrapper for getting one socket connection to server.
 *
 * address[in]			The address to connect.
 * port[in] 			The port number.
 * clientfd[out]		The fd of connection.
 *
 * Return:
 * FUNC_RETURN_OK					Succeed.
 * UTIL_NETWORK_FAIL_CREATESOCKET. 	Fail to call socket().
 * UTIL_NETWORK_FAIL_GETHOST. 		Fail to call gethostbyname().
 * UTIL_NETWORK_FAIL_CONNECT. 		Fail to call connect().
 */
int connectToServerRemote(const char *address, uint16_t port, int *clientfd)
{
	int					fd		= 0;
	int 		    	sockres = 0;
	struct sockaddr_in 	server_addr;
	struct hostent 	   *server  = NULL;

	*clientfd = -1;

	server = gethostbyname(address);
	if ( server == NULL )
	{
		write_log("Failed to get host by name %s for connecting to a remote "
				  "socket server %s:%d (error %s)",
				  address,
				  address,
				  port,
				  hstrerror(h_errno));
		return UTIL_NETWORK_FAIL_GETHOST;
	}

	fd = socket(AF_INET, SOCK_STREAM, 0);
	if ( fd < 0 )
	{
		write_log("Failed to open socket for connecting remote socket server "
				  "(errno %d)",
				  errno);
		return UTIL_NETWORK_FAIL_CREATESOCKET;
	}

	bzero((char *)&server_addr, sizeof(server_addr));
	server_addr.sin_family = AF_INET;
	bcopy((char *)server->h_addr,
		  (char *)&server_addr.sin_addr.s_addr,
		  server->h_length);
	server_addr.sin_port = htons(port);

	while(true)
	{
		sockres = connect(fd,
						  (struct sockaddr *)&server_addr,
						  sizeof(server_addr));
		if( sockres < 0)
		{
			write_log("Failed to connect to remove socket server (errno %d), fd %d",
					  errno,
					  fd);

			if (errno == EINTR)
			{
				continue;
			}
			else
			{
				write_log("Close fd %d at once due to not recoverable error "
						  "detected.",
						  fd);
				closeConnectionRemote(&fd);
				return UTIL_NETWORK_FAIL_CONNECT;
			}
		}
		break;
	}

	*clientfd = fd;
	return FUNC_RETURN_OK;
}
int callSyncRPCRemote(const char     	   *hostname,
					  uint16_t              port,
		  	  	  	  const char 	 	   *sendbuff,
					  int   		  		sendbuffsize,
					  uint16_t		  		sendmsgid,
					  uint16_t 		  		exprecvmsgid,
					  SelfMaintainBuffer 	recvsmb)
{
	int 							fd 			  = -1;
	int 							res 		  = FUNC_RETURN_OK;
	AsyncCommBuffer					newcommbuffer = NULL;
	AsyncCommMessageHandlerContext 	context 	  = NULL;
	SyncRPCContextData 				userdata;

	/* Connect to the server side. */
	res = connectToServerRemote(hostname, port, &fd);
	if ( res != FUNC_RETURN_OK ) {
		elog(WARNING, "Fail to connect to socket server %s:%d, result %d",
				  	  hostname, port,
					  res);
		goto exit;
	}

	initializeSyncRPContent(&userdata, recvsmb, exprecvmsgid);
	context = createMessageHandlerContext(&userdata);

	res = registerFileDesc(fd,
						   NULL,
						   ASYNCCOMM_READBYTES | ASYNCCOMM_WRITEBYTES,
						   &AsyncCommBufferHandlersMessage,
						   context,
						   &newcommbuffer);
	if ( res != FUNC_RETURN_OK )
	{
		rm_pfree(AsyncCommContext, context);
		elog(WARNING, "Fail to register FD for synchronous communication. %d", res);
		goto exit;
	}

	buildMessageToCommBuffer(newcommbuffer,
							 sendbuff,
							 sendbuffsize,
							 sendmsgid,
							 0,
							 0);

	context->AsyncBuffer = newcommbuffer;

	InitHandler_Message(newcommbuffer);

	/* Wait for the complete of the communication. */
	while( true )
	{
		processAllCommFileDescs();
		if ( userdata.CommStatus == SYNC_RPC_COMM_IDLE )
		{
			break;
		}
		else if ( QueryCancelPending )
		{
			/*
			 * We find that this QD wants to cancel the query, we don't need
			 * to continue the communication.
			 */
			res = TRANSCANCEL_INPROGRESS;
			break;
		}
	}

	res = res == TRANSCANCEL_INPROGRESS ? res : userdata.Result;

	/* Close and cleanup */
	closeAndRemoveAllRegisteredFileDesc();

	if (res != FUNC_RETURN_OK)
	{
	  elog(WARNING, "Sync RPC framework (inet) finds exception raised.");
	}
	return res;
exit:
	closeConnectionRemote(&fd);
	return res;
}
示例#4
0
int callSyncRPCRemote(const char     	   *hostname,
					  uint16_t              port,
		  	  	  	  const char 	 	   *sendbuff,
					  int   		  		sendbuffsize,
					  uint16_t		  		sendmsgid,
					  uint16_t 		  		exprecvmsgid,
					  SelfMaintainBuffer 	recvsmb,
					  char				   *errorbuf,
					  int					errorbufsize)
{
	int 							fd 			  = -1;
	int 							res 		  = FUNC_RETURN_OK;
	AsyncCommBuffer					newcommbuffer = NULL;
	AsyncCommMessageHandlerContext 	context 	  = NULL;
	SyncRPCContextData 				userdata;

	/* Connect to the server side. */
	res = connectToServerRemote(hostname, port, &fd);
	if ( res != FUNC_RETURN_OK )
	{
		snprintf(errorbuf, errorbufsize,
				 "failed to connect to remote socket server %s:%d",
				 hostname,
				 port);
		elog(WARNING, "%s", errorbuf);
		goto exit;
	}

	initializeSyncRPContent(&userdata, recvsmb, exprecvmsgid);
	context = createMessageHandlerContext(&userdata);

	res = registerFileDesc(fd,
						   NULL,
						   ASYNCCOMM_READBYTES | ASYNCCOMM_WRITEBYTES,
						   &AsyncCommBufferHandlersMessage,
						   context,
						   &newcommbuffer);
	if ( res != FUNC_RETURN_OK )
	{
		rm_pfree(AsyncCommContext, context);

		snprintf(errorbuf, errorbufsize,
				 "failed to register socket connection fd %d connected to %s:%d "
				 "for resource rpc communication",
				 fd,
				 hostname, port);

		elog(WARNING, "%s", errorbuf);
		goto exit;
	}

	buildMessageToCommBuffer(newcommbuffer,
							 sendbuff,
							 sendbuffsize,
							 sendmsgid,
							 0,
							 0);

	context->AsyncBuffer = newcommbuffer;

	InitHandler_Message(newcommbuffer);

	/* Wait for the complete of the communication. */
	while( true )
	{
		processAllCommFileDescs();
		if ( userdata.CommStatus == SYNC_RPC_COMM_IDLE )
		{
			break;
		}
		else if ( QueryCancelPending )
		{
			/*
			 * We find that this QD wants to cancel the query, we don't need
			 * to continue the communication.
			 */
			res = TRANSCANCEL_INPROGRESS;
			break;
		}
	}

	res = res == TRANSCANCEL_INPROGRESS ? res : userdata.Result;

	/* Close and cleanup */
	closeAndRemoveAllRegisteredFileDesc();

	if (res != FUNC_RETURN_OK)
	{
	  elog(WARNING, "Sync RPC framework (inet) finds exception raised.");

	  switch(res)
	  {
	  case COMM2RM_CLIENT_FAIL_SEND:
		  snprintf(errorbuf, errorbufsize, "failed to send content");
		  break;
	  case COMM2RM_CLIENT_FAIL_RECV:
		  snprintf(errorbuf, errorbufsize, "failed to receive content");
		  break;
	  case REQUESTHANDLER_WRONGMESSAGE:
		  snprintf(errorbuf, errorbufsize, "wrong message was received");
		  break;
	  default:
		  Assert(false);
	  }
	}
	return res;
exit:
	elog(LOG, "Close fd %d at once", fd);
	closeConnectionRemote(&fd);
	return res;
}