Ejemplo n.º 1
0
static void
process_set_configration_parameter(PCP_CONNECTION *frontend,char *buf, int len)
{
	char* param_name;
	char* param_value;
	int wsize;
	char code[] = "CommandComplete";

	param_name = buf;
	if(param_name == NULL)
		ereport(ERROR,
				(errmsg("PCP: set configuration parameter failed"),
				 errdetail("invalid pcp packet received from client")));

	param_value = (char *) memchr(buf, '\0', len);
	if(param_value == NULL)
		ereport(ERROR,
			(errmsg("set configuration parameter failed"),
				 errdetail("invalid pcp packet received from client")));

	param_value +=1;
	ereport(LOG,
			(errmsg("set configuration parameter, \"%s TO %s\"",param_name,param_value)));
	
	if(strcasecmp(param_name, "client_min_messages") == 0)
	{
		const char *ordered_valid_values[] = {"debug5","debug4","debug3","debug2","debug1","log","commerror","info","notice","warning","error",NULL};
		bool found = false;
		int i;
		for(i=0; ; i++)
		{
			char* valid_val = (char*)ordered_valid_values[i];
			if(!valid_val)
				break;

			if (!strcasecmp(param_value, valid_val))
			{
				found = true;
				pool_config->client_min_messages = i + 10;
				ereport(DEBUG1,
					(errmsg("PCP setting parameter \"%s\" to \"%s\"",param_name,param_value)));
				break;
			}
		}
		if (!found)
			ereport(ERROR,
				(errmsg("PCP: set configuration parameter failed"),
					 errdetail("invalid value \"%s\" for parameter \"%s\"",param_value,param_name)));
	}
	else
		ereport(ERROR,
			(errmsg("PCP: set configuration parameter failed"),
				 errdetail("invalid parameter \"%s\"",param_name)));

	pcp_write(frontend, "a", 1);
	wsize = htonl(sizeof(code) + sizeof(int));
	pcp_write(frontend, &wsize, sizeof(int));
	pcp_write(frontend, code, sizeof(code));
	do_pcp_flush(frontend);
}
Ejemplo n.º 2
0
static void
process_detach_node(PCP_CONNECTION *frontend,char *buf, char tos)
{
	int node_id;
	int wsize;
	char code[] = "CommandComplete";
	bool gracefully;

	if (tos == 'D')
		gracefully = false;
	else
		gracefully = true;

	node_id = atoi(buf);
	ereport(DEBUG1,
			(errmsg("PCP: processing detach node"),
			 errdetail("detaching Node ID %d", node_id)));

	pool_detach_node(node_id, gracefully);

	pcp_write(frontend, "d", 1);
	wsize = htonl(sizeof(code) + sizeof(int));
	pcp_write(frontend, &wsize, sizeof(int));
	pcp_write(frontend, code, sizeof(code));
	do_pcp_flush(frontend);
}
Ejemplo n.º 3
0
static void
process_authentication(PCP_CONNECTION *frontend, char *buf, char* salt, int *random_salt)
{
	int wsize;
	int authenticated;

	if (*random_salt)
	{
		authenticated = user_authenticate(buf, pcp_conf_file, salt, 4);
	}
	if (!*random_salt || !authenticated)
	{
		ereport(FATAL,
			(errmsg("authentication failed"),
				 errdetail("username and/or password does not match")));

		*random_salt = 0;
	}
	else
	{
		char code[] = "AuthenticationOK";
		pcp_write(frontend, "r", 1);
		wsize = htonl(sizeof(code) + sizeof(int));
		pcp_write(frontend, &wsize, sizeof(int));
		pcp_write(frontend, code, sizeof(code));
		do_pcp_flush(frontend);
		*random_salt = 0;

		ereport(DEBUG1,
			(errmsg("PCP: processing authentication request"),
				 errdetail("authentication OK")));
	}
}
Ejemplo n.º 4
0
Archivo: pcp.c Proyecto: ysd001/pgpool2
/* --------------------------------
 * pcp_node_info - get information of node pointed by given argument
 *
 * return structure of node information on success, -1 otherwise
 * --------------------------------
 */
PCPResultInfo *
pcp_node_info(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, "I", 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=\"I\", len=%d\n", ntohl(wsize));

	return process_pcp_response(pcpConn,'I');
}
Ejemplo n.º 5
0
static void
process_recovery_request(PCP_CONNECTION *frontend,char *buf)
{
	int wsize;
	char code[] = "CommandComplete";
	int node_id = atoi(buf);

	if ( (node_id < 0) || (node_id >= pool_config->backend_desc->num_backends) )
		ereport(ERROR,
			(errmsg("process recovery request failed"),
				 errdetail("node id %d is not valid", node_id)));

	if ((!REPLICATION &&
		 !(MASTER_SLAVE &&
		   !strcmp(pool_config->master_slave_sub_mode, MODE_STREAMREP))) ||
		(MASTER_SLAVE &&
		 !strcmp(pool_config->master_slave_sub_mode, MODE_STREAMREP) &&
		 node_id == PRIMARY_NODE_ID))
	{
		if (MASTER_SLAVE && !strcmp(pool_config->master_slave_sub_mode, MODE_STREAMREP))
			ereport(ERROR,
				(errmsg("process recovery request failed"),
					 errdetail("primary server cannot be recovered by online recovery.")));
		else
			ereport(ERROR,
				(errmsg("process recovery request failed"),
					 errdetail("recovery request is accepted only in replication mode or stereaming replication mode.")));
	}
	else
	{
		if (pcp_mark_recovery_in_progress() == false)
			ereport(FATAL,
				(errmsg("process recovery request failed"),
					 errdetail("pgpool-II is already processing another recovery request.")));

		ereport(DEBUG1,
			(errmsg("PCP: processing recovery request"),
				 errdetail("start online recovery")));

		PG_TRY();
		{
			start_recovery(node_id);
			finish_recovery();
			pcp_write(frontend, "c", 1);
			wsize = htonl(sizeof(code) + sizeof(int));
			pcp_write(frontend, &wsize, sizeof(int));
			pcp_write(frontend, code, sizeof(code));
			do_pcp_flush(frontend);
			pcp_mark_recovery_finished();
		}
		PG_CATCH();
		{
			finish_recovery();
			pcp_mark_recovery_finished();
			PG_RE_THROW();
			
		}PG_END_TRY();
	}
	do_pcp_flush(frontend);
}
Ejemplo n.º 6
0
Archivo: pcp.c Proyecto: ysd001/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');
}
Ejemplo n.º 7
0
/* --------------------------------
 * pcp_terminate_pgpool - send terminate packet
 *
 * return 0 on success, -1 otherwise
 * --------------------------------
 */
int
pcp_terminate_pgpool(char mode)
{
	int wsize;

	if (pc == NULL)
	{
		if (debug) fprintf(stderr, "DEBUG: connection does not exist\n");
		errorcode = NOCONNERR;
		return -1;
	}

	pcp_write(pc, "T", 1);
	wsize = htonl(sizeof(int) + sizeof(char));
	pcp_write(pc, &wsize, sizeof(int));
	pcp_write(pc, &mode, sizeof(char));
	if (pcp_flush(pc) < 0)
	{
		if (debug) fprintf(stderr, "DEBUG: could not send data to backend\n");
		return -1;
	}
	if (debug) fprintf(stderr, "DEBUG: send: tos=\"T\", len=%d\n", ntohl(wsize));

	return 0;
}
Ejemplo n.º 8
0
static void
send_md5salt(PCP_CONNECTION *frontend, char* salt)
{
	int wsize;
	ereport(DEBUG1,
			(errmsg("PCP: sending md5 salt to client")));

	pool_random_salt(salt);

	pcp_write(frontend, "m", 1);
	wsize = htonl(sizeof(int) + 4);
	pcp_write(frontend, &wsize, sizeof(int));
	pcp_write(frontend, salt, 4);
	do_pcp_flush(frontend);
}
Ejemplo n.º 9
0
static void
process_promote_node(PCP_CONNECTION *frontend, char *buf, char tos)
{
	int node_id;
	int wsize;
	char code[] = "CommandComplete";
	bool gracefully;

	if (tos == 'J')
		gracefully = false;
	else
		gracefully = true;
	
	node_id = atoi(buf);
	if ( (node_id < 0) || (node_id >= pool_config->backend_desc->num_backends) )
		ereport(ERROR,
				(errmsg("could not process recovery request"),
				 errdetail("node id %d is not valid", node_id)));
	/* promoting node is reserved to Streaming Replication */
	if (!MASTER_SLAVE || (strcmp(pool_config->master_slave_sub_mode, MODE_STREAMREP) != 0))
	{
		ereport(FATAL,
			(errmsg("invalid pgpool mode for process recovery request"),
				 errdetail("not in streaming replication mode, can't promote node id %d", node_id)));
		
	}

	if (node_id == PRIMARY_NODE_ID)
	{
		ereport(FATAL,
				(errmsg("invalid pgpool mode for process recovery request"),
				 errdetail("specified node is already primary node, can't promote node id %d", node_id)));
		
	}
	ereport(DEBUG1,
			(errmsg("PCP: processing promote node"),
			 errdetail("promoting Node ID %d", node_id)));
	pool_promote_node(node_id, gracefully);

	pcp_write(frontend, "d", 1);
	wsize = htonl(sizeof(code) + sizeof(int));
	pcp_write(frontend, &wsize, sizeof(int));
	pcp_write(frontend, code, sizeof(code));
	do_pcp_flush(frontend);
}
Ejemplo n.º 10
0
static void
inform_watchdog_info(PCP_CONNECTION *frontend,char *buf)
{
	int wd_index;
	int json_data_len;
	int wsize;
	char code[] = "CommandComplete";
	char* json_data;

	if (!pool_config->use_watchdog)
		ereport(ERROR,
			(errmsg("PCP: informing watchdog info failed"),
				 errdetail("watcdhog is not enabled")));

	wd_index = atoi(buf);

	json_data = wd_get_watchdog_nodes(wd_index);
	if (json_data == NULL)
		ereport(ERROR,
			(errmsg("PCP: informing watchdog info failed"),
				 errdetail("invalid watchdog index")));

	ereport(DEBUG2,
		(errmsg("PCP: informing watchdog info"),
			 errdetail("retrieved node information from IPC socket")));

	/*
	 * This is the voilation of PCP protocol but I think
	 * in future we should shift to more adaptable protocol for
	 * data transmition.
	 */
	json_data_len = strlen(json_data);
	wsize = htonl(sizeof(code) +
				  json_data_len+ 1 +
				  sizeof(int));
	pcp_write(frontend, "w", 1);

	pcp_write(frontend, &wsize, sizeof(int));
	pcp_write(frontend, code, sizeof(code));

	pcp_write(frontend, json_data, json_data_len +1);
	do_pcp_flush(frontend);

	pfree(json_data);
}
Ejemplo n.º 11
0
static void
inform_process_count(PCP_CONNECTION *frontend)
{
	int wsize;
	int process_count;
	char process_count_str[16];
	int *process_list = NULL;
	char code[] = "CommandComplete";
	char *mesg = NULL;
	int i;
	int total_port_len = 0;

	process_list = pool_get_process_list(&process_count);

	mesg = (char *)palloc(6*process_count);	/* port# is at most 5 characters long (MAX:65535) */

	snprintf(process_count_str, sizeof(process_count_str), "%d", process_count);

	for (i = 0; i < process_count; i++)
	{
		char port[6];
		snprintf(port, sizeof(port), "%d", process_list[i]);
		snprintf(mesg+total_port_len, strlen(port)+1, "%s", port);
		total_port_len += strlen(port)+1;
	}

	pcp_write(frontend, "n", 1);
	wsize = htonl(sizeof(code) +
				  strlen(process_count_str)+1 +
				  total_port_len +
				  sizeof(int));
	pcp_write(frontend, &wsize, sizeof(int));
	pcp_write(frontend, code, sizeof(code));
	pcp_write(frontend, process_count_str, strlen(process_count_str)+1);
	pcp_write(frontend, mesg, total_port_len);
	do_pcp_flush(frontend);

	pfree(process_list);
	pfree(mesg);

	ereport(DEBUG1,
		(errmsg("PCP: informing process count"),
			 errdetail("%d process(es) found", process_count)));
}
Ejemplo n.º 12
0
int send_to_pcp_frontend(char* data, int len, bool flush)
{
	int ret;
	if (processType != PT_PCP_WORKER || pcp_frontend == NULL)
		return -1;
	ret = pcp_write(pcp_frontend, data, len);
	if (flush && !ret)
		ret = pcp_flush(pcp_frontend);
	return ret;
}
Ejemplo n.º 13
0
static void
process_shutown_request(PCP_CONNECTION *frontend, char mode)
{
	char code[] = "CommandComplete";
	pid_t ppid = getppid();
	int sig,len;

	if (mode == 's')
	{
		ereport(DEBUG1,
				(errmsg("PCP: processing shutdown request"),
				 errdetail("sending SIGTERM to the parent process with PID:%d", ppid)));
		sig = SIGTERM;
	}
	else if (mode == 'f')
	{
		ereport(DEBUG1,
				(errmsg("PCP: processing shutdown request"),
				 errdetail("sending SIGINT to the parent process with PID:%d", ppid)));
		sig = SIGINT;
	}
	else if (mode == 'i')
	{
		ereport(DEBUG1,
				(errmsg("PCP: processing shutdown request"),
				 errdetail("sending SIGQUIT to the parent process with PID:%d", ppid)));
		sig = SIGQUIT;
	}
	else
	{
		ereport(ERROR,
				(errmsg("PCP: error while processing shutdown request"),
				 errdetail("invalid shutdown mode \"%c\"", mode)));
	}

	pcp_write(frontend, "t", 1);
	len = htonl(sizeof(code) + sizeof(int));
	pcp_write(frontend, &len, sizeof(int));
	pcp_write(frontend, code, sizeof(code));
	do_pcp_flush(frontend);

	pool_signal_parent(sig);
}
Ejemplo n.º 14
0
static void
process_attach_node(PCP_CONNECTION *frontend,char *buf)
{
	int node_id;
	int wsize;
	char code[] = "CommandComplete";

	node_id = atoi(buf);
	ereport(DEBUG1,
			(errmsg("PCP: processing attach node"),
			 errdetail("attaching Node ID %d", node_id)));

	send_failback_request(node_id,true);

	pcp_write(frontend, "c", 1);
	wsize = htonl(sizeof(code) + sizeof(int));
	pcp_write(frontend, &wsize, sizeof(int));
	pcp_write(frontend, code, sizeof(code));
	do_pcp_flush(frontend);
}
Ejemplo n.º 15
0
Archivo: pcp.c Proyecto: 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');
}
Ejemplo n.º 16
0
Archivo: pcp.c Proyecto: 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');
}
Ejemplo n.º 17
0
Archivo: pcp.c Proyecto: ysd001/pgpool2
PCPResultInfo *
pcp_set_backend_parameter(PCPConnInfo* pcpConn,char* parameter_name, char* value)
{
	int wsize;
	char null_chr = 0;

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

	return process_pcp_response(pcpConn,'A');
}
Ejemplo n.º 18
0
Archivo: pcp.c Proyecto: 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;
}
Ejemplo n.º 19
0
static void
inform_node_count(PCP_CONNECTION *frontend)
{
	int wsize;
	char mesg[16];
	char code[] = "CommandComplete";
	int node_count = pool_get_node_count();

	snprintf(mesg, sizeof(mesg), "%d", node_count);

	pcp_write(frontend, "l", 1);
	wsize = htonl(sizeof(code) +
				  strlen(mesg)+1 +
				  sizeof(int));
	pcp_write(frontend, &wsize, sizeof(int));
	pcp_write(frontend, code, sizeof(code));
	pcp_write(frontend, mesg, strlen(mesg)+1);
	do_pcp_flush(frontend);

	ereport(DEBUG1,
			(errmsg("PCP: informing node count"),
			 errdetail("%d node(s) found", node_count)));
}
Ejemplo n.º 20
0
/* --------------------------------
 * pcp_disconnect - close connection to pgpool
 * --------------------------------
 */
void
pcp_disconnect(void)
{
	int wsize;

	if (pc == NULL)
	{
		if (debug) fprintf(stderr, "DEBUG: connection does not exist\n");
		return;
	}

	pcp_write(pc, "X", 1);
	wsize = htonl(sizeof(int));
	pcp_write(pc, &wsize, sizeof(int));
	if (pcp_flush(pc) < 0)
	{
		/* backend had closed connection already */
	}
	if (debug) fprintf(stderr, "DEBUG: send: tos=\"X\", len=%d\n", (int) sizeof(int));

	pcp_close(pc);
	pc = NULL;
}
Ejemplo n.º 21
0
static void
inform_watchdog_info(PCP_CONNECTION *frontend,char *buf)
{
	int wd_index;
	int wsize;
	char code[] = "CommandComplete";
	char pgpool_port_str[6];
	char wd_port_str[6];
	char status[2];

	WdInfo *wi = NULL;

	if (!pool_config->use_watchdog)
		ereport(ERROR,
				(errmsg("PCP: informing watchdog info failed"),
				 errdetail("watcdhog is not enabled")));

	wd_index = atoi(buf);
	wi = wd_get_watchdog_info(wd_index);

	if (wi == NULL)
		ereport(ERROR,
				(errmsg("PCP: informing watchdog info failed"),
				 errdetail("invalid watchdog index")));

	ereport(DEBUG2,
			(errmsg("PCP: informing watchdog info"),
			 errdetail("retrieved node information from shared memory")));

	snprintf(pgpool_port_str, sizeof(pgpool_port_str), "%d", wi->pgpool_port);
	snprintf(wd_port_str, sizeof(wd_port_str), "%d", wi->wd_port);
	snprintf(status, sizeof(status), "%d", wi->status);

	pcp_write(frontend, "w", 1);
	wsize = htonl(sizeof(code) +
				  strlen(wi->hostname)+1 +
				  strlen(pgpool_port_str)+1 +
				  strlen(wd_port_str)+1 +
				  strlen(status)+1 +
				  sizeof(int));
	pcp_write(frontend, &wsize, sizeof(int));
	pcp_write(frontend, code, sizeof(code));

	pcp_write(frontend, wi->hostname, strlen(wi->hostname)+1);
	pcp_write(frontend, pgpool_port_str, strlen(pgpool_port_str)+1);
	pcp_write(frontend, wd_port_str, strlen(wd_port_str)+1);
	pcp_write(frontend, status, strlen(status)+1);
	do_pcp_flush(frontend);
}
Ejemplo n.º 22
0
static void
inform_node_info(PCP_CONNECTION *frontend,char *buf)
{
	int node_id;
	int wsize;
	char port_str[6];
	char status[2];
	char weight_str[20];
	char code[] = "CommandComplete";
	BackendInfo *bi = NULL;

	node_id = atoi(buf);

	bi = pool_get_node_info(node_id);

	if (bi == NULL)
		ereport(ERROR,
				(errmsg("informing node info failed"),
				 errdetail("invalid node ID")));
	
	ereport(DEBUG2,
			(errmsg("PCP: informing node info"),
			 errdetail("retrieved node information from shared memory")));
	
	snprintf(port_str, sizeof(port_str), "%d", bi->backend_port);
	snprintf(status, sizeof(status), "%d", bi->backend_status);
	snprintf(weight_str, sizeof(weight_str), "%f", bi->backend_weight);
	
	pcp_write(frontend, "i", 1);
	wsize = htonl(sizeof(code) +
				  strlen(bi->backend_hostname)+1 +
				  strlen(port_str)+1 +
				  strlen(status)+1 +
				  strlen(weight_str)+1 +
				  sizeof(int));
	pcp_write(frontend, &wsize, sizeof(int));
	pcp_write(frontend, code, sizeof(code));
	pcp_write(frontend, bi->backend_hostname, strlen(bi->backend_hostname)+1);
	pcp_write(frontend, port_str, strlen(port_str)+1);
	pcp_write(frontend, status, strlen(status)+1);
	pcp_write(frontend, weight_str, strlen(weight_str)+1);
	do_pcp_flush(frontend);
}
Ejemplo n.º 23
0
/* --------------------------------
 * pcp_systemdb_info - get information of system DB
 *
 * return structure of system DB information on success, -1 otherwise
 * --------------------------------
 */
SystemDBInfo *
pcp_systemdb_info(void)
{
	char tos;
	char *buf = NULL;
	int wsize;
	int rsize;
	SystemDBInfo *systemdb_info = NULL;
	int offset = 0;

	if (pc == NULL)
	{
		if (debug) fprintf(stderr, "DEBUG: connection does not exist\n");
		errorcode = NOCONNERR;
		return NULL;
	}

	pcp_write(pc, "S", 1);
	wsize = htonl(sizeof(int));
	pcp_write(pc, &wsize, sizeof(int));
	if (pcp_flush(pc) < 0)
	{
		if (debug) fprintf(stderr, "DEBUG: could not send data to backend\n");
		return NULL;
	}
	if (debug) fprintf(stderr, "DEBUG: send: tos=\"S\", len=%d\n", ntohl(wsize));

	while (1) {
		if (pcp_read(pc, &tos, 1))
			return NULL;
		if (pcp_read(pc, &rsize, sizeof(int)))
			return NULL;
		rsize = ntohl(rsize);
		buf = (char *)malloc(rsize);
		if (buf == NULL)
		{
			errorcode = NOMEMERR;
			return NULL;
		}
		if (pcp_read(pc, buf, rsize - sizeof(int)))
		{
			free(buf);
			return NULL;
		}
		if (debug) fprintf(stderr, "DEBUG: recv: tos=\"%c\", len=%d, data=%s\n", tos, rsize, buf);

		if (tos == 'e')
		{
			if (debug) fprintf(stderr, "DEBUG: command failed. reason=%s\n", buf);
			free(buf);
			errorcode = BACKENDERR;
			return NULL;
		}
		else if (tos == 's')
		{
			char *index;

			if (strcmp(buf, "SystemDBInfo") == 0)
			{
				systemdb_info = (SystemDBInfo *)malloc(sizeof(SystemDBInfo));
				if (systemdb_info == NULL)
				{
					free(buf);
					errorcode = NOMEMERR;
					return NULL;
				}

				index = (char *) memchr(buf, '\0', rsize) + 1;
				if (index != NULL)
					systemdb_info->hostname = strdup(index);
				if (systemdb_info->hostname == NULL)
				{
					free(buf);
					free_systemdb_info(systemdb_info);
					errorcode = NOMEMERR;
					return NULL;
				}				
			
				index = (char *) memchr(index, '\0', rsize) + 1;
				if (index != NULL)
					systemdb_info->port = atoi(index);
			
				index = (char *) memchr(index, '\0', rsize) + 1;
				if (index != NULL)
					systemdb_info->user = strdup(index);
				if (systemdb_info->user == NULL)
				{
					free(buf);
					free_systemdb_info(systemdb_info);
					errorcode = NOMEMERR;
					return NULL;
				}

				index = (char *) memchr(index, '\0', rsize) + 1;
				if (index != NULL)
					systemdb_info->password = strdup(index);
				if (systemdb_info->password == NULL)
				{
					free(buf);
					free_systemdb_info(systemdb_info);
					errorcode = NOMEMERR;
					return NULL;
				}

				index = (char *) memchr(index, '\0', rsize) + 1;
				if (index != NULL)
					systemdb_info->schema_name = strdup(index);
				if (systemdb_info->schema_name == NULL)
				{
					free(buf);
					free_systemdb_info(systemdb_info);
					errorcode = NOMEMERR;
					return NULL;
				}

				index = (char *) memchr(index, '\0', rsize) + 1;
				if (index != NULL)
					systemdb_info->database_name = strdup(index);
				if (systemdb_info->database_name == NULL)
				{
					free(buf);
					free_systemdb_info(systemdb_info);
					errorcode = NOMEMERR;
					return NULL;
				}
			
				index = (char *) memchr(index, '\0', rsize) + 1;
				if (index != NULL)
					systemdb_info->dist_def_num = atoi(index);

				index = (char *) memchr(index, '\0', rsize) + 1;
				if (index != NULL)
					systemdb_info->system_db_status = atoi(index);

				if (systemdb_info->dist_def_num > 0)
				{
					systemdb_info->dist_def_slot = NULL;
					systemdb_info->dist_def_slot = (DistDefInfo *)malloc(sizeof(DistDefInfo) * systemdb_info->dist_def_num);
					if (systemdb_info->dist_def_slot == NULL)
					{
						free(buf);
						free_systemdb_info(systemdb_info);
						errorcode = NOMEMERR;
						return NULL;
					}
				}
			}
			else if (strcmp(buf, "DistDefInfo") == 0)
			{
				DistDefInfo *dist_def_info = NULL;
				int i;

				dist_def_info = (DistDefInfo *)malloc(sizeof(DistDefInfo));
				if (dist_def_info == NULL)
				{
					free(buf);
					free_systemdb_info(systemdb_info);
					errorcode = NOMEMERR;
					return NULL;
				}

				index = (char *) memchr(buf, '\0', rsize) + 1;
				if (index != NULL)
					dist_def_info->dbname = strdup(index);
				if (dist_def_info->dbname == NULL)
				{
					free(buf);
					free_systemdb_info(systemdb_info);
					errorcode = NOMEMERR;
					return NULL;
				}
			
				index = (char *) memchr(index, '\0', rsize) + 1;
				if (index != NULL)
					dist_def_info->schema_name = strdup(index);
				if (dist_def_info->schema_name == NULL)
				{
					free(buf);
					free_systemdb_info(systemdb_info);
					errorcode = NOMEMERR;
					return NULL;
				}
			
				index = (char *) memchr(index, '\0', rsize) + 1;
				if (index != NULL)
					dist_def_info->table_name = strdup(index);
				if (dist_def_info->table_name == NULL)
				{
					free(buf);
					free_systemdb_info(systemdb_info);
					errorcode = NOMEMERR;
					return NULL;
				}

				index = (char *) memchr(index, '\0', rsize) + 1;
				if (index != NULL)
					dist_def_info->dist_key_col_name = strdup(index);
				if (dist_def_info->dist_key_col_name == NULL)
				{
					free(buf);
					free_systemdb_info(systemdb_info);
					errorcode = NOMEMERR;
					return NULL;
				}

				index = (char *) memchr(index, '\0', rsize) + 1;
				if (index != NULL)
					dist_def_info->col_num = atoi(index);

				dist_def_info->col_list = NULL;
				dist_def_info->col_list = (char **)malloc(sizeof(char *) * dist_def_info->col_num);
				if (dist_def_info->col_list == NULL)
				{
					free(buf);
					free_systemdb_info(systemdb_info);
					errorcode = NOMEMERR;
					return NULL;
				}
				for (i = 0; i < dist_def_info->col_num; i++)
				{
					index = (char *) memchr(index, '\0', rsize) + 1;
					if (index != NULL)
						dist_def_info->col_list[i] = strdup(index);
					if (dist_def_info->col_list[i] == NULL)
					{
						free(buf);
						free_systemdb_info(systemdb_info);
						errorcode = NOMEMERR;
						return NULL;
					}
				}
			
				dist_def_info->type_list = NULL;
				dist_def_info->type_list = (char **)malloc(sizeof(char *) * dist_def_info->col_num);
				if (dist_def_info->type_list == NULL)
				{
					free(buf);
					free_systemdb_info(systemdb_info);
					errorcode = NOMEMERR;
					return NULL;
				}
				for (i = 0; i < dist_def_info->col_num; i++)
				{
					index = (char *) memchr(index, '\0', rsize) + 1;
					if (index != NULL)
						dist_def_info->type_list[i] = strdup(index);
					if (dist_def_info->type_list[i] == NULL)
					{
						free(buf);
						free_systemdb_info(systemdb_info);
						errorcode = NOMEMERR;
						return NULL;
					}
				}

				index = (char *) memchr(index, '\0', rsize) + 1;
				if (index != NULL)
					dist_def_info->dist_def_func = strdup(index);
				if (dist_def_info->dist_def_func == NULL)
				{
					free(buf);
					free_systemdb_info(systemdb_info);
					errorcode = NOMEMERR;
					return NULL;
				}

				memcpy(&systemdb_info->dist_def_slot[offset++], dist_def_info, sizeof(DistDefInfo));
			}
			else if (strcmp(buf, "CommandComplete") == 0)
			{
				free(buf);
				return systemdb_info;
			}
			else
			{
				/* never reached */
			}
		}
	}
	
	free(buf);
	return NULL;
}
Ejemplo n.º 24
0
/* --------------------------------
 * pcp_node_count - get number of nodes currently connected to pgpool
 *
 * return array of pids on success, NULL otherwise
 * --------------------------------
 */
int *
pcp_process_count(int *pnum)
{
	char tos;
	char *buf = NULL;
	int wsize;
	int rsize;
	
	if (pc == NULL)
	{
		if (debug) fprintf(stderr, "DEBUG: connection does not exist\n");
		errorcode = NOCONNERR;
		return NULL;
	}

	pcp_write(pc, "N", 1);
	wsize = htonl(sizeof(int));
	pcp_write(pc, &wsize, sizeof(int));
	if (pcp_flush(pc) < 0)
	{
		if (debug) fprintf(stderr, "DEBUG: could not send data to backend\n");
		return NULL;
	}
	if (debug) fprintf(stderr, "DEBUG: send: tos=\"N\", len=%d\n", ntohl(wsize));

	if (pcp_read(pc, &tos, 1))
		return NULL;			
	if (pcp_read(pc, &rsize, sizeof(int)))
		return NULL;	
	rsize = ntohl(rsize);
	buf = (char *)malloc(rsize);
	if (buf == NULL)
	{
		errorcode = NOMEMERR;
		return NULL;
	}
	if (pcp_read(pc, buf, rsize - sizeof(int)))
	{
		free(buf);
		return NULL;		
	}
	if (debug) fprintf(stderr, "DEBUG: recv: tos=\"%c\", len=%d, data=%s\n", tos, rsize, buf);

	if (tos == 'e')
	{
		if (debug) fprintf(stderr, "DEBUG: command failed. reason=%s\n", buf);
		free(buf);
		errorcode = BACKENDERR;
		return NULL;
	}
	else if (tos == 'n')
	{
		if (strcmp(buf, "CommandComplete") == 0)
		{
			int process_count;
			int *process_list = NULL;
			char *index = NULL;
			int i;

			index = (char *) memchr(buf, '\0', rsize) + 1;
			process_count = atoi(index);

			process_list = (int *)malloc(sizeof(int) * process_count);
			if (process_list == NULL)
			{
				free(buf);
				errorcode = NOMEMERR;
				return NULL;
			}

			for (i = 0; i < process_count; i++)
			{
				index = (char *) memchr(index, '\0', rsize) + 1;
				process_list[i] = atoi(index);
			}

			*pnum = process_count;
			free(buf);
			return process_list;
		}
	}

	free(buf);
	return NULL;
}
Ejemplo n.º 25
0
/* --------------------------------
 * pcp_process_info - get information of node pointed by given argument
 *
 * return structure of process information on success, -1 otherwise
 * --------------------------------
 */
ProcessInfo *
pcp_process_info(int pid, int *array_size)
{
	int wsize;
	char process_id[16];
	char tos;
	char *buf = NULL;
	int rsize;

	ProcessInfo *process_info = NULL;
	ConnectionInfo *conn_info = NULL;
	int ci_size = 0;
	int offset = 0;

	if (pc == NULL)
	{
		if (debug) fprintf(stderr, "DEBUG: connection does not exist\n");
		errorcode = NOCONNERR;
		return NULL;
	}

	snprintf(process_id, sizeof(process_id), "%d", pid);

	pcp_write(pc, "P", 1);
	wsize = htonl(strlen(process_id)+1 + sizeof(int));
	pcp_write(pc, &wsize, sizeof(int));
	pcp_write(pc, process_id, strlen(process_id)+1);
	if (pcp_flush(pc) < 0)
	{
		if (debug) fprintf(stderr, "DEBUG: could not send data to backend\n");
		return NULL;
	}
	if (debug) fprintf(stderr, "DEBUG: send: tos=\"P\", len=%d\n", ntohl(wsize));

	while (1)
	{
		if (pcp_read(pc, &tos, 1))
			return NULL;
		if (pcp_read(pc, &rsize, sizeof(int)))
			return NULL;
		rsize = ntohl(rsize);
		buf = (char *)malloc(rsize);
		if (buf == NULL)
		{
			errorcode = NOMEMERR;
			return NULL;
		}
		if (pcp_read(pc, buf, rsize - sizeof(int)))
		{
			free(buf);
			return NULL;
		}
		if (debug) fprintf(stderr, "DEBUG: recv: tos=\"%c\", len=%d, data=%s\n", tos, rsize, buf);

		if (tos == 'e')
		{
			if (debug) fprintf(stderr, "DEBUG: command failed. reason=%s\n", buf);
			free(buf);
			errorcode = BACKENDERR;
			return NULL;
		}
		else if (tos == 'p')
		{
			char *index;

			if (strcmp(buf, "ArraySize") == 0)
			{
				index = (char *) memchr(buf, '\0', rsize) + 1;
				if (index != NULL)
					ci_size = atoi(index);

				*array_size = ci_size;

				process_info = (ProcessInfo *)malloc(sizeof(ProcessInfo) * ci_size);
				if (process_info == NULL)
				{
					free(buf);
					errorcode = NOMEMERR;
					return NULL;
				}

				conn_info = (ConnectionInfo *)malloc(sizeof(ConnectionInfo) * ci_size);
				if  (conn_info == NULL)
				{
					free(buf);
					free(process_info);
					errorcode = NOMEMERR;
					return NULL;
				}

				continue;
			}
			else if (strcmp(buf, "ProcessInfo") == 0)
			{
				process_info[offset].connection_info = &conn_info[offset];

				index = (char *) memchr(buf, '\0', rsize) + 1;
				if (index != NULL)
					process_info[offset].pid = atoi(index);
			
				index = (char *) memchr(index, '\0', rsize) + 1;
				if (index != NULL)
					strcpy(process_info[offset].connection_info->database, index);
			
				index = (char *) memchr(index, '\0', rsize) + 1;
				if (index != NULL)
					strcpy(process_info[offset].connection_info->user, index);
			
				index = (char *) memchr(index, '\0', rsize) + 1;
				if (index != NULL)
					process_info[offset].start_time = atol(index);

				index = (char *) memchr(index, '\0', rsize) + 1;
				if (index != NULL)
					process_info[offset].connection_info->create_time = atol(index);

				index = (char *) memchr(index, '\0', rsize) + 1;
				if (index != NULL)
					process_info[offset].connection_info->major = atoi(index);

				index = (char *) memchr(index, '\0', rsize) + 1;
				if (index != NULL)
					process_info[offset].connection_info->minor = atoi(index);

				index = (char *) memchr(index, '\0', rsize) + 1;
				if (index != NULL)
					process_info[offset].connection_info->counter = atoi(index);

				index = (char *) memchr(index, '\0', rsize) + 1;
				if (index != NULL)
					process_info[offset].connection_info->backend_id = atoi(index);

				index = (char *) memchr(index, '\0', rsize) + 1;
				if (index != NULL)
					process_info[offset].connection_info->pid = atoi(index);

				index = (char *) memchr(index, '\0', rsize) + 1;
				if (index != NULL)
					process_info[offset].connection_info->connected = atoi(index);

				offset++;
			}
			else if (strcmp(buf, "CommandComplete") == 0)
			{
				free(buf);
				return process_info;
			}
			else
			{
				/* never reached */
			}
		}
	}

	free(buf);
	return NULL;
}
Ejemplo n.º 26
0
/* --------------------------------
 * pcp_node_info - get information of node pointed by given argument
 *
 * return structure of node information on success, -1 otherwise
 * --------------------------------
 */
BackendInfo *
pcp_node_info(int nid)
{
	int wsize;
	char node_id[16];
	char tos;
	char *buf = NULL;
	int rsize;

	if (pc == NULL)
	{
		if (debug) fprintf(stderr, "DEBUG: connection does not exist\n");
		errorcode = NOCONNERR;
		return NULL;
	}

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

	pcp_write(pc, "I", 1);
	wsize = htonl(strlen(node_id)+1 + sizeof(int));
	pcp_write(pc, &wsize, sizeof(int));
	pcp_write(pc, node_id, strlen(node_id)+1);
	if (pcp_flush(pc) < 0)
	{
		if (debug) fprintf(stderr, "DEBUG: could not send data to backend\n");
		return NULL;
	}
	if (debug) fprintf(stderr, "DEBUG: send: tos=\"I\", len=%d\n", ntohl(wsize));

	if (pcp_read(pc, &tos, 1))
		return NULL;	
	if (pcp_read(pc, &rsize, sizeof(int)))
		return NULL;	
	rsize = ntohl(rsize);
	buf = (char *)malloc(rsize);
	if (buf == NULL)
	{
		errorcode = NOMEMERR;
		return NULL;
	}
	if (pcp_read(pc, buf, rsize - sizeof(int)))
	{
		free(buf);
		return NULL;
	}

	if (debug) fprintf(stderr, "DEBUG: recv: tos=\"%c\", len=%d, data=%s\n", tos, rsize, buf);

	if (tos == 'e')
	{
		if (debug) fprintf(stderr, "DEBUG: command failed. reason=%s\n", buf);
		errorcode = BACKENDERR;
		free(buf);
		return NULL;
	}
	else if (tos == 'i')
	{
		if (strcmp(buf, "CommandComplete") == 0)
		{
			char *index = NULL;
			BackendInfo* backend_info = NULL;

			backend_info = (BackendInfo *)malloc(sizeof(BackendInfo));
			if (backend_info == NULL)
			{
				errorcode = NOMEMERR;
				free(buf);
				return NULL;
			}

 			index = (char *) memchr(buf, '\0', rsize) + 1;
			if (index != NULL)
				strcpy(backend_info->backend_hostname, index);

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

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

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

			free(buf);
			return backend_info;
		}
	}

	free(buf);
	return NULL;
}
Ejemplo n.º 27
0
/* --------------------------------
 * pcp_node_count - get number of nodes currently connected to pgpool
 *
 * return array of node IDs on success, -1 otherwise
 * --------------------------------
 */
int
pcp_node_count(void)
{
	char tos;
	char *buf = NULL;
	int wsize;
	int rsize;
	char *index = NULL;

	if (pc == NULL)
	{
		if (debug) fprintf(stderr, "DEBUG: connection does not exist\n");
		errorcode = NOCONNERR;
		return -1;
	}

	pcp_write(pc, "L", 1);
	wsize = htonl(sizeof(int));
	pcp_write(pc, &wsize, sizeof(int));
	if (pcp_flush(pc) < 0)
	{
		if (debug) fprintf(stderr, "DEBUG: could not send data to backend\n");
		return -1;
	}
	if (debug) fprintf(stderr, "DEBUG: send: tos=\"L\", len=%d\n", ntohl(wsize));

	if (pcp_read(pc, &tos, 1))
		return -1;
	if (pcp_read(pc, &rsize, sizeof(int)))
		return -1;
	rsize = ntohl(rsize);
	buf = (char *)malloc(rsize);
	if (buf == NULL)
	{
		errorcode = NOMEMERR;
		return -1;
	}
	if (pcp_read(pc, buf, rsize - sizeof(int)))
	{
		free(buf);
		return -1;
	}

	if (debug) fprintf(stderr, "DEBUG: recv: tos=\"%c\", len=%d, data=%s\n", tos, rsize, buf);

	if (tos == 'e')
	{
		if (debug) fprintf(stderr, "DEBUG: command failed. reason=%s\n", buf);
		errorcode = BACKENDERR;
	}
	else if (tos == 'l')
	{
		if (strcmp(buf, "CommandComplete") == 0)
		{
			index = (char *) memchr(buf, '\0', rsize) + 1;
			if (index != NULL)
			{
				int ret = atoi(index);
				free(buf);
				return ret;
			}
		}
	}

	free(buf);

	return -1;
}
Ejemplo n.º 28
0
/* --------------------------------
 * pcp_pool_status - return setup parameters and status
 *
 * returns and array of POOL_REPORT_CONFIG, NULL otherwise
 * --------------------------------
 */
POOL_REPORT_CONFIG*
pcp_pool_status(int *array_size)
{
	char tos;
	char *buf = NULL;
	int wsize;
	int rsize;
	POOL_REPORT_CONFIG *status = NULL;
	int ci_size = 0;
	int offset = 0;

	if (pc == NULL)
	{
		if (debug) fprintf(stderr, "DEBUG: connection does not exist\n");
		errorcode = NOCONNERR;
		return NULL;
	}

	pcp_write(pc, "B", 1);
	wsize = htonl(sizeof(int));
	pcp_write(pc, &wsize, sizeof(int));
	if (pcp_flush(pc) < 0)
	{
		if (debug) fprintf(stderr, "DEBUG: could not send data to backend\n");
		return NULL;
	}
	if (debug) fprintf(stderr, "DEBUG pcp_pool_status: send: tos=\"B\", len=%d\n", ntohl(wsize));

	while (1) {
		if (pcp_read(pc, &tos, 1))
			return NULL;
		if (pcp_read(pc, &rsize, sizeof(int)))
			return NULL;
		rsize = ntohl(rsize);
		buf = (char *)malloc(rsize);
		if (buf == NULL)
		{
			errorcode = NOMEMERR;
			return NULL;
		}
		if (pcp_read(pc, buf, rsize - sizeof(int)))
		{
			free(buf);
			return NULL;
		}
		if (debug) fprintf(stderr, "DEBUG: recv: tos=\"%c\", len=%d, data=%s\n", tos, rsize, buf);

		if (tos == 'e')
		{
			if (debug) fprintf(stderr, "DEBUG: command failed. reason=%s\n", buf);
			free(buf);
			errorcode = BACKENDERR;
			return NULL;
		}
		else if (tos == 'b')
		{
			char *index;

			if (strcmp(buf, "ArraySize") == 0)
			{
				index = (char *) memchr(buf, '\0', rsize) + 1;
				ci_size = ntohl(*((int *)index));

				*array_size = ci_size;

				status = (POOL_REPORT_CONFIG *) malloc(ci_size * sizeof(POOL_REPORT_CONFIG));

				continue;
			}
			else if (strcmp(buf, "ProcessConfig") == 0)
			{
				index = (char *) memchr(buf, '\0', rsize) + 1;
				if (index != NULL)
					strcpy(status[offset].name, index);

				index = (char *) memchr(index, '\0', rsize) + 1;
				if (index != NULL)
					strcpy(status[offset].value, index);

				index = (char *) memchr(index, '\0', rsize) + 1;
				if (index != NULL)
					strcpy(status[offset].desc, index);

				offset++;
			}
			else if (strcmp(buf, "CommandComplete") == 0)
			{
				free(buf);
				return status;
			}
			else
			{
				/* never reached */
			}
		}
	}

	free(buf);
	return NULL;
}
Ejemplo n.º 29
0
static int _pcp_promote_node(int nid, bool gracefully)
{
	int wsize;
	char node_id[16];
	char tos;
	char *buf = NULL;
	int rsize;
	char *sendchar;

	if (pc == NULL)
	{
		if (debug) fprintf(stderr, "DEBUG: connection does not exist\n");
		errorcode = NOCONNERR;
		return -1;
	}

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

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

	pcp_write(pc, sendchar, 1);
	wsize = htonl(strlen(node_id)+1 + sizeof(int));
	pcp_write(pc, &wsize, sizeof(int));
	pcp_write(pc, node_id, strlen(node_id)+1);
	if (pcp_flush(pc) < 0)
	{
		if (debug) fprintf(stderr, "DEBUG: could not send data to backend\n");
		return -1;
	}
	if (debug) fprintf(stderr, "DEBUG: send: tos=\"E\", len=%d\n", ntohl(wsize));

	if (pcp_read(pc, &tos, 1))
		return -1;
	if (pcp_read(pc, &rsize, sizeof(int)))
		return -1;
	rsize = ntohl(rsize);
	buf = (char *)malloc(rsize);
	if (buf == NULL)
	{
		errorcode = NOMEMERR;
		return -1;
	}
	if (pcp_read(pc, buf, rsize - sizeof(int)))
	{
		free(buf);
		return -1;
	}
	if (debug) fprintf(stderr, "DEBUG: recv: tos=\"%c\", len=%d, data=%s\n", tos, rsize, buf);

	if (tos == 'e')
	{
		if (debug) fprintf(stderr, "DEBUG: command failed. reason=%s\n", buf);
		errorcode = BACKENDERR;
	}
	else if (tos == 'd')
	{
		/* strcmp() for success message, or fail */
		if(strcmp(buf, "CommandComplete") == 0)
		{
			free(buf);
			return 0;
		}
	}

	free(buf);
	return -1;
}
Ejemplo n.º 30
0
/* --------------------------------
 * pcp_authorize - authenticate with pgpool using username and password
 *
 * return 0 on success, -1 otherwise
 * --------------------------------
 */
static int
pcp_authorize(char *username, char *password)
{
	char tos;
	char *buf = NULL;
	int wsize;
	int rsize;
	char salt[4];
	char encrypt_buf[(MD5_PASSWD_LEN+1)*2];
	char md5[MD5_PASSWD_LEN+1];

	/* request salt */
	pcp_write(pc, "M", 1);
	wsize = htonl(sizeof(int));
	pcp_write(pc, &wsize, sizeof(int));
	if (pcp_flush(pc) < 0)
	{
		if (debug) fprintf(stderr, "DEBUG: could not send data to backend\n");
		return -1;
	}

	if (pcp_read(pc, &tos, 1))
		return -1;
	if (pcp_read(pc, &rsize, sizeof(int)))
		return -1;
	rsize = ntohl(rsize);
	buf = (char *)malloc(rsize);
	if (buf == NULL)
	{
		errorcode = NOMEMERR;
		return -1;
	}
	if (pcp_read(pc, buf, rsize - sizeof(int)))
		return -1;
	memcpy(salt, buf, 4);
	free(buf);

	/* 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(pc, "R", 1);
	wsize = htonl((strlen(username)+1 + strlen(encrypt_buf)+1) + sizeof(int));
	pcp_write(pc, &wsize, sizeof(int));
	pcp_write(pc, username, strlen(username)+1);
	pcp_write(pc, encrypt_buf, strlen(encrypt_buf)+1);
	if (pcp_flush(pc) < 0)
	{
		if  (debug) fprintf(stderr, "DEBUG: could not send data to backend\n");
		return -1;
	}
	if (debug) fprintf(stderr, "DEBUG: send: tos=\"R\", len=%d\n", ntohl(wsize));

	if (pcp_read(pc, &tos, 1))
		return -1;
	if (pcp_read(pc, &rsize, sizeof(int)))
		return -1;
	rsize = ntohl(rsize);
	buf = (char *)malloc(rsize);
	if (buf == NULL)
	{
		errorcode = NOMEMERR;
		return -1;
	}
	if (pcp_read(pc, buf, rsize - sizeof(int)))
		return -1;
	if (debug) fprintf(stderr, "DEBUG: recv: tos=\"%c\", len=%d, data=%s\n", tos, rsize, buf);

	if (tos == 'e')
	{
		if (debug) fprintf(stderr, "DEBUG: command failed. reason=%s\n", buf);
		errorcode = BACKENDERR;
	}
	else if (tos == 'r')
	{
		if (strcmp(buf, "AuthenticationOK") == 0)
		{
			free(buf);
			return 0;
		}

		if (debug) fprintf(stderr, "DEBUG: authentication failed. reason=%s\n", buf);
		errorcode = AUTHERR;
	}
	free(buf);

	return -1;
}