コード例 #1
0
ファイル: pcp.c プロジェクト: pgpool/pgpool2
static PCPResultInfo *
_pcp_promote_node(PCPConnInfo * pcpConn, int nid, bool gracefully)
{
	int			wsize;
	char		node_id[16];
	char	   *sendchar;

	if (PCPConnectionStatus(pcpConn) != PCP_CONNECTION_OK)
	{
		pcp_internal_error(pcpConn, "invalid PCP connection");
		return NULL;
	}

	snprintf(node_id, sizeof(node_id), "%d", nid);

	if (gracefully)
		sendchar = "j";
	else
		sendchar = "J";

	pcp_write(pcpConn->pcpConn, sendchar, 1);
	wsize = htonl(strlen(node_id) + 1 + sizeof(int));
	pcp_write(pcpConn->pcpConn, &wsize, sizeof(int));
	pcp_write(pcpConn->pcpConn, node_id, strlen(node_id) + 1);
	if (PCPFlush(pcpConn) < 0)
		return NULL;
	if (pcpConn->Pfdebug)
		fprintf(pcpConn->Pfdebug, "DEBUG: send: tos=\"E\", len=%d\n", ntohl(wsize));

	return process_pcp_response(pcpConn, 'J');
}
コード例 #2
0
ファイル: pcp.c プロジェクト: pgpool/pgpool2
PCPResultInfo *
pcp_recovery_node(PCPConnInfo * pcpConn, int nid)
{
	int			wsize;
	char		node_id[16];

	if (PCPConnectionStatus(pcpConn) != PCP_CONNECTION_OK)
	{
		pcp_internal_error(pcpConn, "invalid PCP connection");
		return NULL;
	}

	snprintf(node_id, sizeof(node_id), "%d", nid);

	pcp_write(pcpConn->pcpConn, "O", 1);
	wsize = htonl(strlen(node_id) + 1 + sizeof(int));
	pcp_write(pcpConn->pcpConn, &wsize, sizeof(int));
	pcp_write(pcpConn->pcpConn, node_id, strlen(node_id) + 1);
	if (PCPFlush(pcpConn) < 0)
		return NULL;
	if (pcpConn->Pfdebug)
		fprintf(pcpConn->Pfdebug, "DEBUG: send: tos=\"D\", len=%d\n", ntohl(wsize));

	return process_pcp_response(pcpConn, 'O');
}
コード例 #3
0
ファイル: pcp.c プロジェクト: ysd001/pgpool2
static int
PCPFlush(PCPConnInfo* pcpConn)
{
	int ret = pcp_flush(pcpConn->pcpConn);
	if (ret)
		pcp_internal_error(pcpConn,
						   "ERROR: sending data to backend failed with error \"%s\"",strerror(errno));
	return ret;
}
コード例 #4
0
ファイル: pcp.c プロジェクト: pgpool/pgpool2
static void
process_error_response(PCPConnInfo * pcpConn, char toc, char *buf)
{
	/* For time we only support sev, error message and details */
	char	   *errorSev = NULL;
	char	   *errorMsg = NULL;
	char	   *errorDet = NULL;
	char	   *e = buf;

	if (toc != 'E' && toc != 'N')
		return;

	while (*e)
	{
		char		type = *e;

		e++;
		if (*e == 0)
			break;

		if (type == 'M')
			errorMsg = e;
		else if (type == 'S')
			errorSev = e;
		else if (type == 'D')
			errorDet = e;
		else
			e += strlen(e) + 1;
		if (errorDet && errorSev && errorMsg)	/* we have all what we need */
			break;
	}
	if (!errorSev && !errorMsg)
		return;

	if (toc != 'E')				/* This is not an error report it as debug */
	{
		if (pcpConn->Pfdebug)
			fprintf(pcpConn->Pfdebug,
					"BACKEND %s:  %s\n%s%s%s", errorSev, errorMsg,
					errorDet ? "DETAIL:  " : "",
					errorDet ? errorDet : "",
					errorDet ? "\n" : "");
	}
	else
	{
		pcp_internal_error(pcpConn,
						   "%s:  %s\n%s%s%s", errorSev, errorMsg,
						   errorDet ? "DETAIL:  " : "",
						   errorDet ? errorDet : "",
						   errorDet ? "\n" : "");
		setResultStatus(pcpConn, PCP_RES_BACKEND_ERROR);

	}
}
コード例 #5
0
ファイル: pcp.c プロジェクト: ysd001/pgpool2
static void
process_command_complete_response(PCPConnInfo* pcpConn, char* buf, int len)
{
	if (strcmp(buf, "CommandComplete") == 0)
	{
		setCommandSuccessful(pcpConn);
	}
	else
	{
		pcp_internal_error(pcpConn,
						   "command failed with reason: \"%s\"",buf);
	setResultStatus(pcpConn, PCP_RES_BAD_RESPONSE);
	}
}
コード例 #6
0
ファイル: pcp.c プロジェクト: ysd001/pgpool2
static void
process_salt_info_response(PCPConnInfo* pcpConn, char* buf, int len)
{
	char* salt = palloc((sizeof(char) * 4));
	memcpy(salt, buf, 4);
	if (setNextResultBinaryData(pcpConn->pcpResInfo, (void *)salt, 4, NULL) < 0 )
	{
		pcp_internal_error(pcpConn,

						   "command failed. invalid response");
		setResultStatus(pcpConn, PCP_RES_BAD_RESPONSE);
	}
	else
	{
		setCommandSuccessful(pcpConn);
	}
}
コード例 #7
0
ファイル: pcp.c プロジェクト: ysd001/pgpool2
/* --------------------------------
 * pcp_terminate_pgpool - send terminate packet
 *
 * return 0 on success, -1 otherwise
 * --------------------------------
 */
PCPResultInfo *pcp_terminate_pgpool(PCPConnInfo* pcpConn, char mode)
{
	int wsize;

	if(PCPConnectionStatus(pcpConn) != PCP_CONNECTION_OK)
	{
		pcp_internal_error(pcpConn,"invalid PCP connection");
		return NULL;
	}
	pcp_write(pcpConn->pcpConn, "T", 1);
	wsize = htonl(sizeof(int) + sizeof(char));
	pcp_write(pcpConn->pcpConn, &wsize, sizeof(int));
	pcp_write(pcpConn->pcpConn, &mode, sizeof(char));
	if (PCPFlush(pcpConn) < 0)
		return NULL;
	if(pcpConn->Pfdebug)
		fprintf(pcpConn->Pfdebug,"DEBUG: send: tos=\"T\", len=%d\n", ntohl(wsize));

	return process_pcp_response(pcpConn, 'T');
}
コード例 #8
0
ファイル: pcp.c プロジェクト: ysd001/pgpool2
PCPResultInfo*
pcp_pool_status(PCPConnInfo *pcpConn)
{
	int wsize;

	if(PCPConnectionStatus(pcpConn) != PCP_CONNECTION_OK)
	{
		pcp_internal_error(pcpConn,"invalid PCP connection");
		return NULL;
	}

	pcp_write(pcpConn->pcpConn, "B", 1);
	wsize = htonl(sizeof(int));
	pcp_write(pcpConn->pcpConn, &wsize, sizeof(int));
	if (PCPFlush(pcpConn) < 0)
		return NULL;
	if (pcpConn->Pfdebug)
		fprintf(pcpConn->Pfdebug, "DEBUG pcp_pool_status: send: tos=\"B\", len=%d\n", ntohl(wsize));
	return process_pcp_response(pcpConn, 'B');
}
コード例 #9
0
ファイル: pcp.c プロジェクト: ysd001/pgpool2
/* --------------------------------
 * pcp_disconnect - close connection to pgpool
 * --------------------------------
 */
void
pcp_disconnect(PCPConnInfo* pcpConn)
{
	int wsize;

	if(PCPConnectionStatus(pcpConn) != PCP_CONNECTION_OK)
	{
		pcp_internal_error(pcpConn,"invalid PCP connection");
		return;
	}

	pcp_write(pcpConn->pcpConn, "X", 1);
	wsize = htonl(sizeof(int));
	pcp_write(pcpConn->pcpConn, &wsize, sizeof(int));
	if (PCPFlush(pcpConn) < 0)
		return;
	if(pcpConn->Pfdebug)
		fprintf(pcpConn->Pfdebug, "DEBUG: send: tos=\"X\", len=%d\n", (int) sizeof(int));

	pcp_close(pcpConn->pcpConn);
	pcpConn->connState = PCP_CONNECTION_NOT_CONNECTED;
	pcpConn->pcpConn = NULL;
}
コード例 #10
0
ファイル: pcp.c プロジェクト: ysd001/pgpool2
PCPConnInfo*
pcp_connect(char *hostname, int port, char *username, char *password, FILE *Pfdebug)
{
	struct sockaddr_in addr;
	struct sockaddr_un unix_addr;
	struct hostent *hp;
	char *password_fron_file = NULL;
	char   os_user[256];
	PCPConnInfo* pcpConn = palloc0(sizeof(PCPConnInfo));
	int fd;
	int on = 1;
	int len;

	pcpConn->connState = PCP_CONNECTION_NOT_CONNECTED;
	pcpConn->Pfdebug = Pfdebug;

	if (hostname == NULL || *hostname == '\0' || *hostname == '/')
	{
		char *path;

		fd = socket(AF_UNIX, SOCK_STREAM, 0);

		if (fd < 0)
		{
			pcp_internal_error(pcpConn,
							   "ERROR: failed to create UNIX domain socket. socket error \"%s\"",strerror(errno));
			pcpConn->connState = PCP_CONNECTION_BAD;

			return pcpConn;
		}

		memset(&unix_addr, 0, sizeof(unix_addr));
		unix_addr.sun_family = AF_UNIX;

		if (hostname == NULL || *hostname == '\0')
		{
			path = UNIX_DOMAIN_PATH;
			hostname = path;
		}
		else
		{
			path = hostname;
		}

		snprintf(unix_addr.sun_path, sizeof(unix_addr.sun_path), "%s/.s.PGSQL.%d",
				 path, port);

		if (connect(fd, (struct sockaddr *) &unix_addr, sizeof(unix_addr)) < 0)
		{
			close(fd);

			pcp_internal_error(pcpConn,
							   "ERROR: connection to socket \"%s\" failed with error \"%s\"",unix_addr.sun_path,strerror(errno));
			pcpConn->connState = PCP_CONNECTION_BAD;
			return pcpConn;
		}
	}
	else
	{
		fd = socket(AF_INET, SOCK_STREAM, 0);
		if (fd < 0)
		{
			pcp_internal_error(pcpConn,
							   "ERROR: failed to create INET domain socket with error \"%s\"",strerror(errno));
			pcpConn->connState = PCP_CONNECTION_BAD;
			return pcpConn;
		}

		if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY,
					   (char *) &on, sizeof(on)) < 0)
		{
			close(fd);

			pcp_internal_error(pcpConn,
							   "ERROR: set socket option failed with error \"%s\"",strerror(errno));
			pcpConn->connState = PCP_CONNECTION_BAD;
			return pcpConn;
		}

		memset((char *) &addr, 0, sizeof(addr));
		addr.sin_family = AF_INET;
		hp = gethostbyname(hostname);
		if ((hp == NULL) || (hp->h_addrtype != AF_INET))
		{
			close(fd);
			pcp_internal_error(pcpConn,
							   "ERROR: could not retrieve hostname. gethostbyname failed with error \"%s\"",strerror(errno));
			pcpConn->connState = PCP_CONNECTION_BAD;
			return pcpConn;

		}
		memmove((char *) &(addr.sin_addr),
				(char *) hp->h_addr,
				hp->h_length);
		addr.sin_port = htons(port);

		len = sizeof(struct sockaddr_in);
		if (connect(fd, (struct sockaddr *) &addr, len) < 0)
		{
			close(fd);
			pcp_internal_error(pcpConn,
							   "ERROR: connection to host \"%s\" failed with error \"%s\"",hostname,strerror(errno));
			pcpConn->connState = PCP_CONNECTION_BAD;
			return pcpConn;
		}
	}

	pcpConn->pcpConn = pcp_open(fd);
	if (pcpConn->pcpConn == NULL)
	{
		close(fd);
		pcp_internal_error(pcpConn,
						   "ERROR: failed to allocate memory");
		pcpConn->connState = PCP_CONNECTION_BAD;
		return pcpConn;
	}
	pcpConn->connState = PCP_CONNECTION_CONNECTED;

	/*
	 * If username is not provided. Use the os user name
	 * and do not complain if it (getting os user name) gets failed
	 */
	if (username == NULL && get_os_username(os_user, sizeof(os_user)))
		username = os_user;

	/*
	 * If password is not provided. lookup in pcppass file
	 */
	if (password == NULL || *password == '\0')
	{
		char port_str[100];
		snprintf(port_str, sizeof(port_str), "%d",port);
		password_fron_file = PasswordFromFile(pcpConn, hostname, port_str, username);
		password = password_fron_file;
	}

	if (pcp_authorize(pcpConn,username, password) < 0)
	{
		pcp_close(pcpConn->pcpConn);
		pcpConn->pcpConn = NULL;
		pcpConn->connState = PCP_CONNECTION_AUTH_ERROR;
	}
	else
		pcpConn->connState = PCP_CONNECTION_OK;

	if(password_fron_file)
		pfree(password_fron_file);

	return pcpConn;
}
コード例 #11
0
ファイル: pcp.c プロジェクト: ysd001/pgpool2
static void
process_process_info_response(PCPConnInfo* pcpConn, char* buf, int len)
{
	char *index;
	ProcessInfo *processInfo = NULL;

	if (strcmp(buf, "ArraySize") == 0)
	{
		int ci_size;
		index = (char *) memchr(buf, '\0', len);
		if(index == NULL)
			goto INVALID_RESPONSE;
		index +=1;
		ci_size = atoi(index);

		setResultStatus(pcpConn, PCP_RES_INCOMPLETE);
		setResultSlotCount(pcpConn, ci_size);
		pcpConn->pcpResInfo->nextFillSlot = 0;
		return;
	}
	else if (strcmp(buf, "ProcessInfo") == 0)
	{
		if(PCPResultStatus(pcpConn->pcpResInfo) != PCP_RES_INCOMPLETE)
			goto INVALID_RESPONSE;

		processInfo = palloc0(sizeof(ProcessInfo));
		processInfo->connection_info = palloc0(sizeof(ConnectionInfo));

		index = (char *) memchr(buf, '\0', len);
		if(index == NULL)
			goto INVALID_RESPONSE;
		index +=1;
		processInfo->pid = atoi(index);

		index = (char *) memchr(index, '\0', len);
		if(index == NULL)
			goto INVALID_RESPONSE;
		index +=1;
		strlcpy(processInfo->connection_info->database, index, SM_DATABASE);

		index = (char *) memchr(index, '\0', len);
		if(index == NULL)
			goto INVALID_RESPONSE;
		index +=1;
		strlcpy(processInfo->connection_info->user, index, SM_USER);

		index = (char *) memchr(index, '\0', len);
		if(index == NULL)
			goto INVALID_RESPONSE;
		index +=1;
		processInfo->start_time = atol(index);

		index = (char *) memchr(index, '\0', len);
		if(index == NULL)
			goto INVALID_RESPONSE;
		index +=1;
		processInfo->connection_info->create_time = atol(index);

		index = (char *) memchr(index, '\0', len);
		if(index == NULL)
			goto INVALID_RESPONSE;
		index +=1;
		processInfo->connection_info->major = atoi(index);

		index = (char *) memchr(index, '\0', len);
		if(index == NULL)
			goto INVALID_RESPONSE;
		index +=1;
		processInfo->connection_info->minor = atoi(index);

		index = (char *) memchr(index, '\0', len);
		if(index == NULL)
			goto INVALID_RESPONSE;
		index +=1;
		processInfo->connection_info->counter = atoi(index);

		index = (char *) memchr(index, '\0', len);
		if(index == NULL)
			goto INVALID_RESPONSE;
		index +=1;
		processInfo->connection_info->backend_id = atoi(index);

		index = (char *) memchr(index, '\0', len);
		if(index == NULL)
			goto INVALID_RESPONSE;
		index +=1;
		processInfo->connection_info->pid = atoi(index);

		index = (char *) memchr(index, '\0', len);
		if(index == NULL)
			goto INVALID_RESPONSE;
		index +=1;
		processInfo->connection_info->connected = atoi(index);

		if (setNextResultBinaryData(pcpConn->pcpResInfo, (void *)processInfo, sizeof(ProcessInfo), free_processInfo) < 0)
			goto INVALID_RESPONSE;

		return;
	}

	else if (strcmp(buf, "CommandComplete") == 0)
	{
		setResultStatus(pcpConn, PCP_RES_COMMAND_OK);
		return;
	}

INVALID_RESPONSE:
											   
	if(processInfo)
	{
		if(processInfo->connection_info)
			pfree(processInfo->connection_info);
		pfree(processInfo);
	}
	pcp_internal_error(pcpConn,
					   "command failed. invalid response");
	setResultStatus(pcpConn, PCP_RES_BAD_RESPONSE);
}
コード例 #12
0
ファイル: pcp.c プロジェクト: ysd001/pgpool2
static void
process_node_info_response(PCPConnInfo* pcpConn, char* buf, int len)
{
	BackendInfo* backend_info = NULL;
	if (strcmp(buf, "CommandComplete") == 0)
	{
		char *index = NULL;

		backend_info = (BackendInfo *)palloc(sizeof(BackendInfo));

		index = (char *) memchr(buf, '\0', len);
		if(index == NULL)
			goto INVALID_RESPONSE;
		index +=1;
		strlcpy(backend_info->backend_hostname, index, sizeof(backend_info->backend_hostname));

		index = (char *) memchr(index, '\0', len);
		if(index == NULL)
			goto INVALID_RESPONSE;
		index +=1;
		backend_info->backend_port = atoi(index);

		index = (char *) memchr(index, '\0', len);
		if(index == NULL)
			goto INVALID_RESPONSE;
		index +=1;
		backend_info->backend_status = atoi(index);

		index = (char *) memchr(index, '\0', len);
		if(index == NULL)
			goto INVALID_RESPONSE;
		index +=1;
		backend_info->backend_weight = atof(index);

		index = (char *) memchr(index, '\0', len);
		if(index == NULL)
			goto INVALID_RESPONSE;

		index++;
		backend_info->role = atoi(index);

		index = (char *) memchr(index, '\0', len);
		if(index == NULL)
			goto INVALID_RESPONSE;

		index++;
		backend_info->standby_delay = atol(index);

		index = (char *) memchr(index, '\0', len);
		if(index == NULL)
			goto INVALID_RESPONSE;

		index++;
		backend_info->status_changed_time = atol(index);

		index = (char *) memchr(index, '\0', len);
		if(index == NULL)
			goto INVALID_RESPONSE;

		if (setNextResultBinaryData(pcpConn->pcpResInfo, (void *)backend_info, sizeof(BackendInfo) , NULL) < 0)
			goto INVALID_RESPONSE;

		setCommandSuccessful(pcpConn);
	}
	else
	{
		pcp_internal_error(pcpConn,
						   "command failed with reason: \"%s\"",buf);
		setResultStatus(pcpConn, PCP_RES_BAD_RESPONSE);
	}

	return;

INVALID_RESPONSE:

	if(backend_info)
		pfree(backend_info);
	pcp_internal_error(pcpConn,
					   "command failed. invalid response");
	setResultStatus(pcpConn, PCP_RES_BAD_RESPONSE);

}
コード例 #13
0
ファイル: pcp.c プロジェクト: ysd001/pgpool2
static PCPResultInfo* process_pcp_response(PCPConnInfo* pcpConn, char sentMsg)
{
	char toc;
	int rsize;
	char* buf;

	/* create empty result */
	if(pcpConn->pcpResInfo == NULL)
	{
		pcpConn->pcpResInfo = palloc0(sizeof(PCPResultInfo));
		pcpConn->pcpResInfo->resultSlots = 1;
	}

	while (1) {
		if (pcp_read(pcpConn->pcpConn, &toc, 1))
		{
			pcp_internal_error(pcpConn,
							   "ERROR: unable to read data from socket.");
			setResultStatus(pcpConn, PCP_RES_ERROR);
			return pcpConn->pcpResInfo;
		}
		if (pcp_read(pcpConn->pcpConn, &rsize, sizeof(int)))
		{
			pcp_internal_error(pcpConn,
							   "ERROR: unable to read data from socket.");
			setResultStatus(pcpConn, PCP_RES_ERROR);
			return pcpConn->pcpResInfo;
		}
		rsize = ntohl(rsize);
		buf = (char *)palloc(rsize);

		if (pcp_read(pcpConn->pcpConn, buf, rsize - sizeof(int)))
		{
			pfree(buf);
			pcp_internal_error(pcpConn,
							   "ERROR: unable to read data from socket.");
			setResultStatus(pcpConn, PCP_RES_ERROR);
			return pcpConn->pcpResInfo;
		}

		if(pcpConn->Pfdebug)
			fprintf(pcpConn->Pfdebug, "DEBUG: recv: tos=\"%c\", len=%d\n", toc, rsize);

		switch (toc) {
			case 'r': /* Authentication Response */
			{
				if(sentMsg != 'R')
				{
					setResultStatus(pcpConn, PCP_RES_BAD_RESPONSE);
				}
				else if (strcmp(buf, "AuthenticationOK") == 0)
				{
					pcpConn->connState = PCP_CONNECTION_OK;
					setResultStatus(pcpConn, PCP_RES_COMMAND_OK);
				}
				else
				{
					pcp_internal_error(pcpConn,
									   "ERROR: authentication failed. reason=\"%s\"", buf);
					setResultStatus(pcpConn, PCP_RES_BACKEND_ERROR);
				}
			}
			break;
			case 'm':
				if(sentMsg != 'M')
					setResultStatus(pcpConn, PCP_RES_BAD_RESPONSE);
				else
					process_salt_info_response(pcpConn,buf,rsize);
				break;

			case 'E':
				setResultStatus(pcpConn, PCP_RES_BACKEND_ERROR);
				process_error_response(pcpConn,toc,buf);
				break;

			case 'N':
				process_error_response(pcpConn,toc,buf);
				pfree(buf);
				continue;
				break;

			case 'i':
				if(sentMsg != 'I')
					setResultStatus(pcpConn, PCP_RES_BAD_RESPONSE);
				else
					process_node_info_response(pcpConn,buf,rsize);
				break;

			case 'l':
				if(sentMsg != 'L')
					setResultStatus(pcpConn, PCP_RES_BAD_RESPONSE);
				else
					process_pcp_node_count_response(pcpConn,buf,rsize);
				break;

			case 'c':
				if(sentMsg != 'C' && sentMsg != 'O')
					setResultStatus(pcpConn, PCP_RES_BAD_RESPONSE);
				else
					process_command_complete_response(pcpConn,buf,rsize);
				break;

			case 'd':
				if(sentMsg != 'D' && sentMsg != 'J')
					setResultStatus(pcpConn, PCP_RES_BAD_RESPONSE);
				else
					process_command_complete_response(pcpConn,buf,rsize);
				break;

			case 'a':
				if(sentMsg != 'A')
					setResultStatus(pcpConn, PCP_RES_BAD_RESPONSE);
				else
					process_command_complete_response(pcpConn,buf,rsize);
				break;

			case 'w':
				if(sentMsg != 'W')
					setResultStatus(pcpConn, PCP_RES_BAD_RESPONSE);
				else
					process_watchdog_info_response(pcpConn,buf,rsize);
				break;

			case 'p':
				if(sentMsg != 'P')
					setResultStatus(pcpConn, PCP_RES_BAD_RESPONSE);
				else
					process_process_info_response(pcpConn,buf,rsize);
				break;

			case 'n':
				if(sentMsg != 'N')
					setResultStatus(pcpConn, PCP_RES_BAD_RESPONSE);
				else
					process_process_count_response(pcpConn,buf,rsize);
				break;

			case 'b':
				if(sentMsg != 'B')
					setResultStatus(pcpConn, PCP_RES_BAD_RESPONSE);
				else
					process_pool_status_response(pcpConn,buf,rsize);
				break;

			case 't':
				if(sentMsg != 'T')
					setResultStatus(pcpConn, PCP_RES_BAD_RESPONSE);
				else
					setResultStatus(pcpConn, PCP_RES_COMMAND_OK);
				break;

			default:
				setResultStatus(pcpConn, PCP_RES_BAD_RESPONSE);
				pcp_internal_error(pcpConn,
								   "ERROR: invalid PCP packet type =\"%c\"", toc);
				break;
		}
		pfree(buf);
		if( PCPResultStatus(pcpConn->pcpResInfo) != PCP_RES_INCOMPLETE)
			break;
	}
	return pcpConn->pcpResInfo;
}
コード例 #14
0
ファイル: pcp.c プロジェクト: ysd001/pgpool2
/* --------------------------------
 * pcp_authorize - authenticate with pgpool using username and password
 *
 * return 0 on success, -1 otherwise
 * --------------------------------
 */
static int
pcp_authorize(PCPConnInfo* pcpConn, char *username, char *password)
{
	int wsize;
	char salt[4];
	char* salt_ptr;
	char encrypt_buf[(MD5_PASSWD_LEN+1)*2];
	char md5[MD5_PASSWD_LEN+1];
	PCPResultInfo* pcpRes;

	if (password == NULL)
		password = "";

	if (username == NULL)
		username = "";

	if (PCPConnectionStatus(pcpConn) != PCP_CONNECTION_CONNECTED)
	{
		pcp_internal_error(pcpConn,
						   "ERROR: PCP authorization failed. invalid connection state.");
		return -1;
	}

	if (strlen(username) >= MAX_USER_PASSWD_LEN)
	{
		pcp_internal_error(pcpConn,
						   "ERROR: PCP authorization failed. username too long.");
		return -1;
	}

	/* request salt */
	pcp_write(pcpConn->pcpConn, "M", 1);
	wsize = htonl(sizeof(int));
	pcp_write(pcpConn->pcpConn, &wsize, sizeof(int));
	if (PCPFlush(pcpConn) < 0)
		return -1;

	pcpRes = process_pcp_response(pcpConn, 'M');
	if(PCPResultStatus(pcpRes) != PCP_RES_COMMAND_OK)
		return -1;

	salt_ptr = pcp_get_binary_data(pcpRes, 0);
	if(salt_ptr == NULL)
		return -1;
	memcpy(salt, salt_ptr, 4);

	/* encrypt password */
	pool_md5_hash(password, strlen(password), md5);
	md5[MD5_PASSWD_LEN] = '\0';

	pool_md5_encrypt(md5, username, strlen(username),
					 encrypt_buf + MD5_PASSWD_LEN + 1);
	encrypt_buf[(MD5_PASSWD_LEN+1)*2-1] = '\0';

	pool_md5_encrypt(encrypt_buf+MD5_PASSWD_LEN+1, salt, 4,
					 encrypt_buf);
	encrypt_buf[MD5_PASSWD_LEN] = '\0';

	pcp_write(pcpConn->pcpConn, "R", 1);
	wsize = htonl((strlen(username)+1 + strlen(encrypt_buf)+1) + sizeof(int));
	pcp_write(pcpConn->pcpConn, &wsize, sizeof(int));
	pcp_write(pcpConn->pcpConn, username, strlen(username)+1);
	pcp_write(pcpConn->pcpConn, encrypt_buf, strlen(encrypt_buf)+1);
	if (PCPFlush(pcpConn) < 0)
		return -1;
	pcpRes = process_pcp_response(pcpConn, 'R');
	if(PCPResultStatus(pcpRes) != PCP_RES_COMMAND_OK)
		return -1;
	pcp_free_result(pcpConn);
	return 0;
}
コード例 #15
0
ファイル: pcp.c プロジェクト: ysd001/pgpool2
static void
process_watchdog_info_response(PCPConnInfo* pcpConn, char* buf, int len)
{
	char *json_data = NULL;
	PCPWDClusterInfo* wd_cluster_info = NULL;
	int clusterDataSize = 0;
	if (strcmp(buf, "CommandComplete") == 0)
	{
		int tempVal;
		char* ptr;
		json_data = (char *) memchr(buf, '\0', len);
		if(json_data == NULL)
			goto INVALID_RESPONSE;
		json_data +=1;

		json_value* root;
		json_value* value;
		int i,nodeCount;

		root = json_parse(json_data,len);

		/* The root node must be object */
		if (root == NULL || root->type != json_object)
		{
			json_value_free(root);
			goto INVALID_RESPONSE;
		}

		if (json_get_int_value_for_key(root, "NodeCount", &nodeCount))
		{
			json_value_free(root);
			goto INVALID_RESPONSE;
		}

		/* find the WatchdogNodes array */
		value = json_get_value_for_key(root,"WatchdogNodes");
		if (value == NULL)
		{
			json_value_free(root);
			goto INVALID_RESPONSE;
		}
		if (value->type != json_array)
		{
			json_value_free(root);
			goto INVALID_RESPONSE;
		}
		if (nodeCount != value->u.array.length)
		{
			json_value_free(root);
			goto INVALID_RESPONSE;
		}

		/* create the cluster object */
		clusterDataSize = sizeof(PCPWDClusterInfo) + (sizeof(PCPWDNodeInfo) * nodeCount);
		wd_cluster_info = malloc(clusterDataSize);

		wd_cluster_info->nodeCount = nodeCount;

		if (json_get_int_value_for_key(root, "RemoteNodeCount", &wd_cluster_info->remoteNodeCount))
		{
			json_value_free(root);
			goto INVALID_RESPONSE;
		}
		if (json_get_int_value_for_key(root, "QuorumStatus", &wd_cluster_info->quorumStatus))
		{
			json_value_free(root);
			goto INVALID_RESPONSE;
		}
		if (json_get_int_value_for_key(root, "AliveNodeCount", &wd_cluster_info->aliveNodeCount))
		{
			json_value_free(root);
			goto INVALID_RESPONSE;
		}
		if (json_get_int_value_for_key(root, "Escalated", &tempVal))
		{
			json_value_free(root);
			goto INVALID_RESPONSE;
		}
		wd_cluster_info->escalated = tempVal==0?false:true;

		ptr = json_get_string_value_for_key(root, "MasterNodeName");
		if (ptr == NULL)
		{
			json_value_free(root);
			goto INVALID_RESPONSE;
		}
		strncpy(wd_cluster_info->masterNodeName, ptr, sizeof(wd_cluster_info->masterNodeName) -1);

		ptr = json_get_string_value_for_key(root, "MasterHostName");
		if (ptr == NULL)
		{
			json_value_free(root);
			goto INVALID_RESPONSE;
		}
		strncpy(wd_cluster_info->masterHostName, ptr, sizeof(wd_cluster_info->masterHostName) -1);

		/* Get watchdog nodes data */
		for (i = 0; i < nodeCount; i++)
		{
			char* ptr;
			json_value* nodeInfoValue = value->u.array.values[i];
			PCPWDNodeInfo* wdNodeInfo = &wd_cluster_info->nodeList[i];

			if (nodeInfoValue->type != json_object)
			{
				json_value_free(root);
				goto INVALID_RESPONSE;
			}

			if (json_get_int_value_for_key(nodeInfoValue, "ID", &wdNodeInfo->id))
			{
				json_value_free(root);
				goto INVALID_RESPONSE;
			}

			ptr = json_get_string_value_for_key(nodeInfoValue, "NodeName");
			if (ptr == NULL)
			{
				json_value_free(root);
				goto INVALID_RESPONSE;
			}
			strncpy(wdNodeInfo->nodeName, ptr, sizeof(wdNodeInfo->nodeName) -1);

			ptr = json_get_string_value_for_key(nodeInfoValue, "HostName");
			if (ptr == NULL)
			{
				json_value_free(root);
				goto INVALID_RESPONSE;
			}
			strncpy(wdNodeInfo->hostName, ptr, sizeof(wdNodeInfo->hostName) -1);

			ptr = json_get_string_value_for_key(nodeInfoValue, "DelegateIP");
			if (ptr == NULL)
			{
				json_value_free(root);
				goto INVALID_RESPONSE;
			}
			strncpy(wdNodeInfo->delegate_ip, ptr, sizeof(wdNodeInfo->delegate_ip) -1);

			if (json_get_int_value_for_key(nodeInfoValue, "WdPort", &wdNodeInfo->wd_port))
			{
				json_value_free(root);
				goto INVALID_RESPONSE;
			}

			if (json_get_int_value_for_key(nodeInfoValue, "PgpoolPort", &wdNodeInfo->pgpool_port))
			{
				json_value_free(root);
				goto INVALID_RESPONSE;
			}

			if (json_get_int_value_for_key(nodeInfoValue, "State", &wdNodeInfo->state))
			{
				json_value_free(root);
				goto INVALID_RESPONSE;
			}

			ptr = json_get_string_value_for_key(nodeInfoValue, "StateName");
			if (ptr == NULL)
			{
				json_value_free(root);
				goto INVALID_RESPONSE;
			}
			strncpy(wdNodeInfo->stateName, ptr, sizeof(wdNodeInfo->stateName) -1);
			
			if (json_get_int_value_for_key(nodeInfoValue, "Priority", &wdNodeInfo->wd_priority))
			{
				json_value_free(root);
				goto INVALID_RESPONSE;
			}

		}
		json_value_free(root);

		if (setNextResultBinaryData(pcpConn->pcpResInfo, (void *)wd_cluster_info,clusterDataSize , NULL) < 0)
			goto INVALID_RESPONSE;
		
		setCommandSuccessful(pcpConn);
	}
	else
	{
		pcp_internal_error(pcpConn,
						   "command failed with reason: \"%s\"\n",buf);
		setResultStatus(pcpConn, PCP_RES_BAD_RESPONSE);
	}
	return;

INVALID_RESPONSE:
	
	if(wd_cluster_info)
		pfree(wd_cluster_info);
	pcp_internal_error(pcpConn,
					   "command failed. invalid response\n");
	setResultStatus(pcpConn, PCP_RES_BAD_RESPONSE);
}
コード例 #16
0
ファイル: pcp.c プロジェクト: pgpool/pgpool2
/* --------------------------------
 * pcp_pool_status - return setup parameters and status
 *
 * returns and array of POOL_REPORT_CONFIG, NULL otherwise
 * --------------------------------
 */
static void
process_pool_status_response(PCPConnInfo * pcpConn, char *buf, int len)
{
	char	   *index;
	POOL_REPORT_CONFIG *status = NULL;

	if (strcmp(buf, "ArraySize") == 0)
	{
		int			ci_size;

		index = (char *) memchr(buf, '\0', len) + 1;
		ci_size = ntohl(*((int *) index));

		setResultStatus(pcpConn, PCP_RES_INCOMPLETE);
		setResultSlotCount(pcpConn, ci_size);
		pcpConn->pcpResInfo->nextFillSlot = 0;
		return;
	}
	else if (strcmp(buf, "ProcessConfig") == 0)
	{
		if (PCPResultStatus(pcpConn->pcpResInfo) != PCP_RES_INCOMPLETE)
			goto INVALID_RESPONSE;

		status = palloc(sizeof(POOL_REPORT_CONFIG));

		index = (char *) memchr(buf, '\0', len);
		if (index == NULL)
			goto INVALID_RESPONSE;
		index += 1;
		strlcpy(status->name, index, POOLCONFIG_MAXNAMELEN + 1);

		index = (char *) memchr(index, '\0', len);
		if (index == NULL)
			goto INVALID_RESPONSE;
		index += 1;
		strlcpy(status->value, index, POOLCONFIG_MAXVALLEN + 1);

		index = (char *) memchr(index, '\0', len);
		if (index == NULL)
			goto INVALID_RESPONSE;
		index += 1;
		strlcpy(status->desc, index, POOLCONFIG_MAXDESCLEN + 1);

		if (setNextResultBinaryData(pcpConn->pcpResInfo, (void *) status, sizeof(POOL_REPORT_CONFIG), NULL) < 0)
			goto INVALID_RESPONSE;
		return;
	}
	else if (strcmp(buf, "CommandComplete") == 0)
	{
		setResultStatus(pcpConn, PCP_RES_COMMAND_OK);
		return;
	}

INVALID_RESPONSE:

	if (status)
		pfree(status);
	pcp_internal_error(pcpConn,
					   "command failed. invalid response");
	setResultStatus(pcpConn, PCP_RES_BAD_RESPONSE);
}