Пример #1
0
/* --------------------------------
 * pcp_connect - open connection to pgpool using given arguments
 *
 * return 0 on success, -1 otherwise
 * --------------------------------
 */
int
pcp_connect(char *hostname, int port, char *username, char *password)
{
	struct sockaddr_in addr;
	struct sockaddr_un unix_addr;
	struct hostent *hp;
	int fd;
	int on = 1;
	int len;

	if (pc != NULL)
	{
		if (debug) fprintf(stderr, "DEBUG: connection to backend \"%s\" already exists\n", hostname);
		return 0;
	}

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

		fd = socket(AF_UNIX, SOCK_STREAM, 0);

		if (fd < 0)
		{
			if (debug) fprintf(stderr, "DEBUG: could not create socket\n");
			errorcode = SOCKERR;
			return -1;
		}

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

		if (hostname == NULL || *hostname == '\0')
		{
			path = UNIX_DOMAIN_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)
		{
			if (debug) fprintf(stderr, "DEBUG: could not connect to \"%s\"\n", unix_addr.sun_path);
			close(fd);
			errorcode = CONNERR;
			return -1;
		}
	}
	else
	{
		fd = socket(AF_INET, SOCK_STREAM, 0);
		if (fd < 0)
		{
		  	if (debug) fprintf(stderr, "DEBUG: could not create socket\n");
			errorcode = SOCKERR;
			return -1;
		}

		if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY,
					   (char *) &on, sizeof(on)) < 0)
		{
			if (debug) fprintf(stderr, "DEBUG: could not set socket option\n");
			close(fd);
			errorcode = SOCKERR;
			return -1;
		}

		memset((char *) &addr, 0, sizeof(addr));
		addr.sin_family = AF_INET;
		hp = gethostbyname(hostname);
		if ((hp == NULL) || (hp->h_addrtype != AF_INET))
		{
			if (debug) fprintf(stderr, "DEBUG: could not retrieve hostname\n");
			close(fd);
			errorcode = HOSTERR;
			return -1;
		}
		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)
		{
			if (debug) fprintf(stderr, "DEBUG: could not connect to \"%s\"\n", hostname);
			close(fd);
			errorcode = CONNERR;
			return -1;
		}
	}

	pc = pcp_open(fd);
	if (pc == NULL)
	{
		if (debug) fprintf(stderr, "DEBUG: could not allocate buffer space\n");
		close(fd);
		return -1;
	}

	if (pcp_authorize(username, password) < 0)
	{
		pcp_close(pc);
		pc = NULL;
		return -1;
	}

	return 0;
}
Пример #2
0
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;
}