Back out V6 code, caused postmaster startup failure.

This commit is contained in:
Bruce Momjian 2002-12-06 04:37:05 +00:00
parent 4bfd1ad9e0
commit 38ffbb95d5
13 changed files with 276 additions and 645 deletions

View File

@ -1,5 +1,5 @@
dnl Process this file with autoconf to produce a configure script. dnl Process this file with autoconf to produce a configure script.
dnl $Header: /cvsroot/pgsql/configure.in,v 1.220 2002/12/06 03:46:24 momjian Exp $ dnl $Header: /cvsroot/pgsql/configure.in,v 1.221 2002/12/06 04:37:02 momjian Exp $
dnl dnl
dnl Developers, please strive to achieve this order: dnl Developers, please strive to achieve this order:
dnl dnl
@ -1182,7 +1182,6 @@ AC_CONFIG_LINKS([
src/include/dynloader.h:src/backend/port/dynloader/${template}.h src/include/dynloader.h:src/backend/port/dynloader/${template}.h
src/include/pg_config_os.h:src/include/port/${template}.h src/include/pg_config_os.h:src/include/port/${template}.h
src/Makefile.port:src/makefiles/Makefile.${template} src/Makefile.port:src/makefiles/Makefile.${template}
src/interfaces/libpq/v6util.c:src/backend/libpq/v6util.c
]) ])
AC_CONFIG_HEADERS([src/include/pg_config.h], AC_CONFIG_HEADERS([src/include/pg_config.h],

View File

@ -4,7 +4,7 @@
# Makefile for libpq subsystem (backend half of libpq interface) # Makefile for libpq subsystem (backend half of libpq interface)
# #
# IDENTIFICATION # IDENTIFICATION
# $Header: /cvsroot/pgsql/src/backend/libpq/Makefile,v 1.34 2002/12/06 03:46:24 momjian Exp $ # $Header: /cvsroot/pgsql/src/backend/libpq/Makefile,v 1.35 2002/12/06 04:37:02 momjian Exp $
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
@ -15,7 +15,7 @@ include $(top_builddir)/src/Makefile.global
# be-fsstubs is here for historical reasons, probably belongs elsewhere # be-fsstubs is here for historical reasons, probably belongs elsewhere
OBJS = be-fsstubs.o be-secure.o auth.o crypt.o hba.o md5.o pqcomm.o \ OBJS = be-fsstubs.o be-secure.o auth.o crypt.o hba.o md5.o pqcomm.o \
pqformat.o pqsignal.o v6util.o pqformat.o pqsignal.o
all: SUBSYS.o all: SUBSYS.o

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/libpq/auth.c,v 1.93 2002/12/06 03:46:24 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/libpq/auth.c,v 1.94 2002/12/06 04:37:02 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -410,12 +410,9 @@ ClientAuthentication(Port *port)
*/ */
{ {
const char *hostinfo = "localhost"; const char *hostinfo = "localhost";
char ip_hostinfo[INET6_ADDRSTRLEN];
if (isAF_INETx(&port->raddr.sa) ){
hostinfo = SockAddr_ntop(&port->raddr, ip_hostinfo,
INET6_ADDRSTRLEN, 1);
}
if (port->raddr.sa.sa_family == AF_INET)
hostinfo = inet_ntoa(port->raddr.in.sin_addr);
elog(FATAL, elog(FATAL,
"No pg_hba.conf entry for host %s, user %s, database %s", "No pg_hba.conf entry for host %s, user %s, database %s",
hostinfo, port->user, port->database); hostinfo, port->user, port->database);

View File

@ -10,7 +10,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/libpq/hba.c,v 1.89 2002/12/06 03:46:26 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/libpq/hba.c,v 1.90 2002/12/06 04:37:02 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -582,8 +582,9 @@ parse_hba(List *line, hbaPort *port, bool *found_p, bool *error_p)
} }
else if (strcmp(token, "host") == 0 || strcmp(token, "hostssl") == 0) else if (strcmp(token, "host") == 0 || strcmp(token, "hostssl") == 0)
{ {
SockAddr file_ip_addr, mask; struct in_addr file_ip_addr,
mask;
if (strcmp(token, "hostssl") == 0) if (strcmp(token, "hostssl") == 0)
{ {
#ifdef USE_SSL #ifdef USE_SSL
@ -618,25 +619,16 @@ parse_hba(List *line, hbaPort *port, bool *found_p, bool *error_p)
if (!line) if (!line)
goto hba_syntax; goto hba_syntax;
token = lfirst(line); token = lfirst(line);
if (!inet_aton(token, &file_ip_addr))
if(SockAddr_pton(&file_ip_addr, token, strlen(token)) < 0){ goto hba_syntax;
goto hba_syntax;
}
/* Read the mask field. */ /* Read the mask field. */
line = lnext(line); line = lnext(line);
if (!line) if (!line)
goto hba_syntax; goto hba_syntax;
token = lfirst(line); token = lfirst(line);
if (!inet_aton(token, &mask))
if(SockAddr_pton(&mask, token, strlen(token)) < 0){ goto hba_syntax;
goto hba_syntax;
}
if(file_ip_addr.sa.sa_family != mask.sa.sa_family){
goto hba_syntax;
}
/* Read the rest of the line. */ /* Read the rest of the line. */
line = lnext(line); line = lnext(line);
@ -647,7 +639,8 @@ parse_hba(List *line, hbaPort *port, bool *found_p, bool *error_p)
goto hba_syntax; goto hba_syntax;
/* Must meet network restrictions */ /* Must meet network restrictions */
if (!isAF_INETx(&port->raddr) || !rangeSockAddr(&port->raddr, &file_ip_addr, &mask)) if (port->raddr.sa.sa_family != AF_INET ||
((file_ip_addr.s_addr ^ port->raddr.in.sin_addr.s_addr) & mask.s_addr) != 0)
return; return;
} }
else else

View File

@ -44,6 +44,5 @@
# TYPE DATABASE USER IP-ADDRESS IP-MASK METHOD # TYPE DATABASE USER IP-ADDRESS IP-MASK METHOD
local all all trust local all all trust
host all all 127.0.0.1 255.255.255.255 trust host all all 127.0.0.1 255.255.255.255 trust
host all all ::1 ffff:ffff:ffff:ffff:ffff:ffff trust

View File

@ -29,7 +29,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: pqcomm.c,v 1.142 2002/12/06 03:46:28 momjian Exp $ * $Id: pqcomm.c,v 1.143 2002/12/06 04:37:02 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -85,11 +85,6 @@ extern ssize_t secure_read(Port *, void *, size_t);
extern ssize_t secure_write(Port *, const void *, size_t); extern ssize_t secure_write(Port *, const void *, size_t);
static void pq_close(void); static void pq_close(void);
#ifdef HAVE_UNIX_SOCKETS
int StreamServerPortSubAFUNIX1(unsigned short portNumber,
char *unixSocketName );
int StreamServerPortSubAFUNIX2(void);
#endif /* HAVE_UNIX_SOCKETS */
/* /*
@ -187,198 +182,170 @@ int
StreamServerPort(int family, char *hostName, unsigned short portNumber, StreamServerPort(int family, char *hostName, unsigned short portNumber,
char *unixSocketName, int *fdP) char *unixSocketName, int *fdP)
{ {
int fd, SockAddr saddr;
err; int fd,
int maxconn; err;
int one = 1; int maxconn;
size_t len = 0;
int one = 1;
int ret; Assert(family == AF_INET || family == AF_UNIX);
struct addrinfo* addrs = NULL;
struct addrinfo hint;
char portNumberStr[64];
char* service = portNumberStr;
char* hostn = (hostName[0] == '\0')? NULL : hostName;
Assert(family == AF_INET6 || family == AF_INET || family == AF_UNIX); if ((fd = socket(family, SOCK_STREAM, 0)) < 0)
{
elog(LOG, "StreamServerPort: socket() failed: %m");
return STATUS_ERROR;
}
memset(&hint, 0, sizeof(hint)); if (family == AF_INET)
hint.ai_family = family; {
hint.ai_flags = AI_PASSIVE; if ((setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *) &one,
hint.ai_socktype = SOCK_STREAM; sizeof(one))) == -1)
{
elog(LOG, "StreamServerPort: setsockopt(SO_REUSEADDR) failed: %m");
return STATUS_ERROR;
}
}
snprintf(portNumberStr, sizeof(portNumberStr)/sizeof(char), MemSet((char *) &saddr, 0, sizeof(saddr));
"%d", portNumber); saddr.sa.sa_family = family;
#ifdef HAVE_UNIX_SOCKETS #ifdef HAVE_UNIX_SOCKETS
if (family == AF_UNIX) { if (family == AF_UNIX)
if(StreamServerPortSubAFUNIX1(portNumber, unixSocketName) != STATUS_OK){ {
return STATUS_ERROR; UNIXSOCK_PATH(saddr.un, portNumber, unixSocketName);
} len = UNIXSOCK_LEN(saddr.un);
service = sock_path; strcpy(sock_path, saddr.un.sun_path);
}
/*
* Grab an interlock file associated with the socket file.
*/
if (!CreateSocketLockFile(sock_path, true))
return STATUS_ERROR;
/*
* Once we have the interlock, we can safely delete any
* pre-existing socket file to avoid failure at bind() time.
*/
unlink(sock_path);
}
#endif /* HAVE_UNIX_SOCKETS */ #endif /* HAVE_UNIX_SOCKETS */
if (family == AF_INET)
{
/* TCP/IP socket */
if (hostName[0] == '\0')
saddr.in.sin_addr.s_addr = htonl(INADDR_ANY);
else
{
struct hostent *hp;
hp = gethostbyname(hostName);
if ((hp == NULL) || (hp->h_addrtype != AF_INET))
{
elog(LOG, "StreamServerPort: gethostbyname(%s) failed",
hostName);
return STATUS_ERROR;
}
memmove((char *) &(saddr.in.sin_addr), (char *) hp->h_addr,
hp->h_length);
}
ret = getaddrinfo2(hostn, service, &hint, &addrs); saddr.in.sin_port = htons(portNumber);
if(ret || addrs == NULL){ len = sizeof(struct sockaddr_in);
elog(LOG, "FATAL: StreamServerPort: getaddrinfo2() failed: %s\n", }
gai_strerror(ret));
freeaddrinfo2(hint.ai_family, addrs);
return STATUS_ERROR;
}
err = bind(fd, (struct sockaddr *) & saddr.sa, len);
/** YY DEBUG if (err < 0)
if(addrs->ai_family == AF_UNIX){ {
printf("%s-%s-%s \n", "debug: AF_UNIX!", unixSocketName, hostName); if (family == AF_UNIX)
} elog(LOG, "StreamServerPort: bind() failed: %m\n"
else { "\tIs another postmaster already running on port %d?\n"
printf("%s", "debug: NOT AF_UNIX!\n"); "\tIf not, remove socket node (%s) and retry.",
} (int) portNumber, sock_path);
fflush(stdout); else
**/ elog(LOG, "StreamServerPort: bind() failed: %m\n"
"\tIs another postmaster already running on port %d?\n"
if( (fd = socket(addrs->ai_family, SOCK_STREAM, 0)) < 0){ "\tIf not, wait a few seconds and retry.",
elog(LOG, "FATAL: StreamServerPort: socket() failed: %s\n", (int) portNumber);
strerror(errno)); return STATUS_ERROR;
freeaddrinfo2(hint.ai_family, addrs); }
return STATUS_ERROR;
}
if( isAF_INETx2(family) ){
if ((setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char*)&one,
sizeof(one) )) == -1 ){
elog(LOG, "FATAL: StreamServerPort: setsockopt(SO_REUSEADDR) failed: %s\n",
strerror(errno));
freeaddrinfo2(hint.ai_family, addrs);
return STATUS_ERROR;
}
}
err = bind(fd, addrs->ai_addr, addrs->ai_addrlen);
if(err < 0){
elog(LOG, "FATAL: StreamServerPort: bind() failed: %s\n"
"\tIs another postmaster already running on port %d?\n",
strerror(errno), (int) portNumber);
if (family == AF_UNIX)
elog(LOG, "\tIf not, remove socket node (%s) and retry.\n",
sock_path);
else
elog(LOG, "\tIf not, wait a few seconds and retry.\n");
freeaddrinfo2(hint.ai_family, addrs);
return STATUS_ERROR;
}
#ifdef HAVE_UNIX_SOCKETS #ifdef HAVE_UNIX_SOCKETS
if (family == AF_UNIX){ if (family == AF_UNIX)
if(StreamServerPortSubAFUNIX2() != STATUS_OK){ {
freeaddrinfo2(hint.ai_family, addrs); /* Arrange to unlink the socket file at exit */
return STATUS_ERROR; on_proc_exit(StreamDoUnlink, 0);
}
}
#endif
/* /*
* Select appropriate accept-queue length limit. PG_SOMAXCONN is only * Fix socket ownership/permission if requested. Note we must do
* intended to provide a clamp on the request on platforms where an * this before we listen() to avoid a window where unwanted
* overly large request provokes a kernel error (are there any?). * connections could get accepted.
*/ */
maxconn = MaxBackends * 2; Assert(Unix_socket_group);
if (maxconn > PG_SOMAXCONN) if (Unix_socket_group[0] != '\0')
maxconn = PG_SOMAXCONN; {
char *endptr;
unsigned long int val;
gid_t gid;
err = listen(fd, maxconn); val = strtoul(Unix_socket_group, &endptr, 10);
if (err < 0) { if (*endptr == '\0')
elog(LOG, "FATAL: StreamServerPort: listen() failed: %s\n", {
strerror(errno)); /* numeric group id */
freeaddrinfo2(hint.ai_family, addrs); gid = val;
return STATUS_ERROR; }
} else
{
/* convert group name to id */
struct group *gr;
*fdP = fd; gr = getgrnam(Unix_socket_group);
freeaddrinfo2(hint.ai_family, addrs); if (!gr)
return STATUS_OK; {
elog(LOG, "No such group as '%s'",
} Unix_socket_group);
return STATUS_ERROR;
#ifdef HAVE_UNIX_SOCKETS }
int StreamServerPortSubAFUNIX1(unsigned short portNumber, gid = gr->gr_gid;
char *unixSocketName ) }
{ if (chown(sock_path, -1, gid) == -1)
SockAddr saddr; {
int len; elog(LOG, "Could not set group of %s: %m",
sock_path);
MemSet((char *) &saddr, 0, sizeof(saddr)); return STATUS_ERROR;
}
UNIXSOCK_PATH(saddr.un, portNumber, unixSocketName); }
len = UNIXSOCK_LEN(saddr.un);
strcpy(sock_path, saddr.un.sun_path);
/*
* Grab an interlock file associated with the socket file.
*/
if (!CreateSocketLockFile(sock_path, true))
return STATUS_ERROR;
/*
* Once we have the interlock, we can safely delete any
* pre-existing socket file to avoid failure at bind() time.
*/
unlink(sock_path);
return STATUS_OK;
}
int StreamServerPortSubAFUNIX2(void)
{
/* Arrange to unlink the socket file at exit */
on_proc_exit(StreamDoUnlink, 0);
/*
* Fix socket ownership/permission if requested. Note we must do
* this before we listen() to avoid a window where unwanted
* connections could get accepted.
*/
Assert(Unix_socket_group);
if (Unix_socket_group[0] != '\0') {
char *endptr;
unsigned long int val;
gid_t gid;
val = strtoul(Unix_socket_group, &endptr, 10);
if (*endptr == '\0'){ /* numeric group id */
gid = val;
}
else { /* convert group name to id */
struct group *gr;
gr = getgrnam(Unix_socket_group);
if (!gr) {
elog(LOG, "FATAL: no such group '%s'\n",
Unix_socket_group);
return STATUS_ERROR;
}
gid = gr->gr_gid;
}
if (chown(sock_path, -1, gid) == -1){
elog(LOG, "FATAL: could not set group of %s: %s\n",
sock_path, strerror(errno));
return STATUS_ERROR;
}
}
if (chmod(sock_path, Unix_socket_permissions) == -1){
elog(LOG, "FATAL: could not set permissions on %s: %s\n",
sock_path, strerror(errno));
return STATUS_ERROR;
}
return STATUS_OK;
}
if (chmod(sock_path, Unix_socket_permissions) == -1)
{
elog(LOG, "Could not set permissions on %s: %m",
sock_path);
return STATUS_ERROR;
}
}
#endif /* HAVE_UNIX_SOCKETS */ #endif /* HAVE_UNIX_SOCKETS */
/*
* Select appropriate accept-queue length limit. PG_SOMAXCONN is only
* intended to provide a clamp on the request on platforms where an
* overly large request provokes a kernel error (are there any?).
*/
maxconn = MaxBackends * 2;
if (maxconn > PG_SOMAXCONN)
maxconn = PG_SOMAXCONN;
err = listen(fd, maxconn);
if (err < 0)
{
elog(LOG, "StreamServerPort: listen() failed: %m");
return STATUS_ERROR;
}
*fdP = fd;
return STATUS_OK;
}
/* /*
* StreamConnection -- create a new connection with client using * StreamConnection -- create a new connection with client using
@ -424,20 +391,8 @@ StreamConnection(int server_fd, Port *port)
return STATUS_ERROR; return STATUS_ERROR;
} }
/* DEBUG YY
{
char l_hostinfo[INET6_ADDRSTRLEN];
char r_hostinfo[INET6_ADDRSTRLEN];
SockAddr_ntop(&port->laddr, l_hostinfo, INET6_ADDRSTRLEN, 1);
SockAddr_ntop(&port->raddr, r_hostinfo, INET6_ADDRSTRLEN, 1);
printf("StreamConnect() l: %s r: %s\n", l_hostinfo, r_hostinfo);
printf("StreamConnect() l: %d r: %d\n", port->laddr.sa.sa_family,
port->raddr.sa.sa_family);
}
*/
/* select NODELAY and KEEPALIVE options if it's a TCP connection */ /* select NODELAY and KEEPALIVE options if it's a TCP connection */
if ( isAF_INETx(&port->laddr) ) if (port->laddr.sa.sa_family == AF_INET)
{ {
int on = 1; int on = 1;

View File

@ -1,300 +0,0 @@
#include "postgres.h"
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/in.h>
#ifdef HAVE_NETINET_TCP_H
#include <netinet/tcp.h>
#endif
#include <arpa/inet.h>
#include <sys/file.h>
#include "libpq/libpq.h"
#include "miscadmin.h"
#ifdef HAVE_UNIX_SOCKETS
static int ga_unix(const char* path, const struct addrinfo* hintsp,
struct addrinfo** result);
#endif /* HAVE_UNIX_SOCKETS */
int getaddrinfo2(const char* hostname, const char* servname,
const struct addrinfo* hintp, struct addrinfo **result)
{
#ifdef HAVE_UNIX_SOCKETS
if( hintp != NULL && hintp->ai_family == AF_UNIX){
return ga_unix(servname, hintp, result);
}
else {
#endif /* HAVE_UNIX_SOCKETS */
return getaddrinfo(hostname, servname, hintp, result);
#ifdef HAVE_UNIX_SOCKETS
}
#endif /* HAVE_UNIX_SOCKETS */
}
void freeaddrinfo2(int hint_ai_family, struct addrinfo *ai)
{
#ifdef HAVE_UNIX_SOCKETS
if(hint_ai_family == AF_UNIX){
struct addrinfo *p;
while(ai != NULL){
p = ai;
ai = ai->ai_next;
free(p->ai_addr);
free(p);
}
}
else {
#endif /* HAVE_UNIX_SOCKETS */
freeaddrinfo(ai);
#ifdef HAVE_UNIX_SOCKETS
}
#endif /* HAVE_UNIX_SOCKETS */
}
#ifdef HAVE_UNIX_SOCKETS
/**
* Bug: only one addrinfo is set even though hintsp is NULL or
* ai_socktype is 0
* AI_CANNONNAME does not support.
*/
static int ga_unix(const char* path, const struct addrinfo* hintsp,
struct addrinfo** result)
{
struct addrinfo hints;
struct addrinfo* aip;
struct sockaddr_un* unp;
memset(&hints, 0, sizeof(hints));
if(hintsp == NULL){
hints.ai_family = AF_UNIX;
hints.ai_socktype = SOCK_STREAM;
}
else {
memcpy(&hints, hintsp, sizeof(hints));
}
if(hints.ai_socktype == 0){
hints.ai_socktype = SOCK_STREAM;
}
if(!(hints.ai_family == AF_UNIX)){
printf("hints.ai_family is invalied ga_unix()\n");
return EAI_ADDRFAMILY;
}
aip = calloc(1, sizeof(struct addrinfo));
if(aip == NULL){
return EAI_MEMORY;
}
aip->ai_family = AF_UNIX;
aip->ai_socktype = hints.ai_socktype;
aip->ai_protocol = hints.ai_protocol;
aip->ai_next = NULL;
aip->ai_canonname = NULL;
*result = aip;
unp = calloc(1, sizeof(struct sockaddr_un));
if(aip == NULL){
return EAI_MEMORY;
}
unp->sun_family = AF_UNIX;
aip->ai_addr = (struct sockaddr*) unp;
aip->ai_addrlen = sizeof(struct sockaddr_un);
if(strlen(path) >= sizeof(unp->sun_path)){
return EAI_SERVICE;
}
strcpy(unp->sun_path, path);
#if SALEN
unp->sun_len = sizeof(struct sockaddr_un);
#endif /* SALEN */
if(hints.ai_flags & AI_PASSIVE){
unlink(unp->sun_path);
}
return 0;
}
#endif /* HAVE_UNIX_SOCKETS */
/**
* SockAddr_ntop - set IP address string from SockAddr
*
* parameters... sa : SockAddr union
* dst : buffer for address string
* cnt : sizeof dst
* v4conv: non-zero: if address is IPv4 mapped IPv6 address then
* convert to IPv4 address.
* returns... pointer to dst
* if sa.sa_family is not AF_INET or AF_INET6 dst is set as empy string.
*/
char* SockAddr_ntop(const SockAddr* sa, char* dst, size_t cnt, int v4conv)
{
switch(sa->sa.sa_family){
case AF_INET:
inet_ntop(AF_INET, &sa->in.sin_addr, dst, cnt);
break;
case AF_INET6:
inet_ntop(AF_INET6, &sa->in6.sin6_addr, dst, cnt);
if(v4conv && IN6_IS_ADDR_V4MAPPED(&sa->in6.sin6_addr) ){
strcpy(dst, dst + 7);
}
break;
default:
dst[0] = '\0';
break;
}
return dst;
}
int SockAddr_pton(SockAddr* sa, const char* src, size_t cnt)
{
int i;
int family = AF_INET;
for(i = 0; i < cnt; i++){
if(src[i] == ':'){
family = AF_INET6;
break;
}
}
sa->sa.sa_family = family;
switch(family){
case AF_INET:
return inet_pton(AF_INET, src, &sa->in.sin_addr);
case AF_INET6:
return inet_pton(AF_INET6, src, &sa->in6.sin6_addr);
break;
default:
return -1;
}
}
/**
* isAF_INETx - check to see if sa is AF_INET or AF_INET6
*
* parameters... sa : SockAddr union
* returns...
* if sa->sa.sa_famil is AF_INET or AF_INET6 then
* return 1
* else
* return 0
*/
int isAF_INETx(const SockAddr* sa)
{
if(sa->sa.sa_family == AF_INET ||
sa->sa.sa_family == AF_INET6
){
return 1;
}
else {
return 0;
}
}
int isAF_INETx2(int family)
{
if(family == AF_INET ||
family == AF_INET6
){
return 1;
}
else {
return 0;
}
}
int rangeSockAddr(const SockAddr* addr, const SockAddr* netaddr, const SockAddr* netmask)
{
if(addr->sa.sa_family == AF_INET){
return rangeSockAddrAF_INET(addr, netaddr, netmask);
}
else if(addr->sa.sa_family == AF_INET6){
return rangeSockAddrAF_INET6(addr, netaddr, netmask);
}
else {
return 0;
}
}
int rangeSockAddrAF_INET(const SockAddr* addr, const SockAddr* netaddr,
const SockAddr* netmask)
{
if(addr->sa.sa_family != AF_INET ||
netaddr->sa.sa_family != AF_INET ||
netmask->sa.sa_family != AF_INET ){
return 0;
}
if( ((addr->in.sin_addr.s_addr ^ netaddr->in.sin_addr.s_addr ) &
netmask->in.sin_addr.s_addr) == 0){
return 1;
}
else {
return 0;
}
}
int rangeSockAddrAF_INET6(const SockAddr* addr, const SockAddr* netaddr,
const SockAddr* netmask)
{
int i;
if(IN6_IS_ADDR_V4MAPPED(&addr->in6.sin6_addr) ){
SockAddr addr4;
convSockAddr6to4(addr, &addr4);
if(rangeSockAddrAF_INET(&addr4, netaddr, netmask)){
return 1;
}
}
if(netaddr->sa.sa_family != AF_INET6 ||
netmask->sa.sa_family != AF_INET6 ){
return 0;
}
for( i = 0; i < 16; i++){
if( ((addr->in6.sin6_addr.s6_addr[i] ^ netaddr->in6.sin6_addr.s6_addr[i] ) &
netmask->in6.sin6_addr.s6_addr[i] ) != 0){
return 0;
}
}
return 1;
}
void convSockAddr6to4(const SockAddr* src, SockAddr* dst)
{
char addr_str[INET6_ADDRSTRLEN];
dst->in.sin_family = AF_INET;
dst->in.sin_port = src->in6.sin6_port;
dst->in.sin_addr.s_addr = src->in6.sin6_addr.s6_addr32[3];
SockAddr_ntop(src, addr_str, INET6_ADDRSTRLEN, 0);
}

View File

@ -37,7 +37,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.300 2002/12/06 03:46:29 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.301 2002/12/06 04:37:02 momjian Exp $
* *
* NOTES * NOTES
* *
@ -669,7 +669,7 @@ PostmasterMain(int argc, char *argv[])
*/ */
if (NetServer) if (NetServer)
{ {
status = StreamServerPort(AF_INET6, VirtualHost, status = StreamServerPort(AF_INET, VirtualHost,
(unsigned short) PostPortNumber, (unsigned short) PostPortNumber,
UnixSocketDir, UnixSocketDir,
&ServerSock_INET); &ServerSock_INET);
@ -2091,14 +2091,13 @@ DoBackend(Port *port)
/* /*
* Get the remote host name and port for logging and status display. * Get the remote host name and port for logging and status display.
*/ */
if (isAF_INETx(&port->raddr)) if (port->raddr.sa.sa_family == AF_INET)
{ {
unsigned short remote_port; unsigned short remote_port;
char *host_addr; char *host_addr;
char ip_hostinfo[INET6_ADDRSTRLEN];
remote_port = ntohs(port->raddr.in.sin_port); remote_port = ntohs(port->raddr.in.sin_port);
host_addr = SockAddr_ntop(&port->raddr, ip_hostinfo, INET6_ADDRSTRLEN, 1); host_addr = inet_ntoa(port->raddr.in.sin_addr);
remote_host = NULL; remote_host = NULL;

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: libpq.h,v 1.53 2002/12/06 03:46:32 momjian Exp $ * $Id: libpq.h,v 1.54 2002/12/06 04:37:05 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -19,7 +19,6 @@
#include "lib/stringinfo.h" #include "lib/stringinfo.h"
#include "libpq/libpq-be.h" #include "libpq/libpq-be.h"
#include "libpq/v6util.h"
/* ---------------- /* ----------------
* PQArgBlock * PQArgBlock

View File

@ -9,7 +9,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: pqcomm.h,v 1.71 2002/12/06 03:46:33 momjian Exp $ * $Id: pqcomm.h,v 1.72 2002/12/06 04:37:05 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -47,7 +47,6 @@ typedef union SockAddr
{ {
struct sockaddr sa; struct sockaddr sa;
struct sockaddr_in in; struct sockaddr_in in;
struct sockaddr_in6 in6;
struct sockaddr_un un; struct sockaddr_un un;
} SockAddr; } SockAddr;

View File

@ -1,17 +0,0 @@
#ifndef V6UTIL_H
#define V6UTIL_H
void freeaddrinfo2(int hint_ai_family, struct addrinfo *ai);
int getaddrinfo2(const char* hostname, const char* servname,
const struct addrinfo* hintp, struct addrinfo **result);
char* SockAddr_ntop(const SockAddr* sa, char* dst, size_t cnt, int v4conv);
int SockAddr_pton(SockAddr* sa, const char* src, size_t cnt);
int isAF_INETx(const SockAddr* sa);
int isAF_INETx2(int family);
int rangeSockAddr(const SockAddr* addr, const SockAddr* netaddr, const SockAddr* netmask);
int rangeSockAddrAF_INET(const SockAddr* addr, const SockAddr* netaddr,
const SockAddr* netmask);
int rangeSockAddrAF_INET6(const SockAddr* addr, const SockAddr* netaddr,
const SockAddr* netmask);
void convSockAddr6to4(const SockAddr* src, SockAddr* dst);
#endif /* V6UTIL_H */

View File

@ -4,7 +4,7 @@
# #
# Copyright (c) 1994, Regents of the University of California # Copyright (c) 1994, Regents of the University of California
# #
# $Header: /cvsroot/pgsql/src/interfaces/libpq/Makefile,v 1.67 2002/12/06 03:46:37 momjian Exp $ # $Header: /cvsroot/pgsql/src/interfaces/libpq/Makefile,v 1.68 2002/12/06 04:37:05 momjian Exp $
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
@ -23,7 +23,6 @@ override CPPFLAGS := -I$(srcdir) $(CPPFLAGS) -DFRONTEND -DSYSCONFDIR='"$(sysconf
OBJS= fe-auth.o fe-connect.o fe-exec.o fe-misc.o fe-print.o fe-lobj.o \ OBJS= fe-auth.o fe-connect.o fe-exec.o fe-misc.o fe-print.o fe-lobj.o \
pqexpbuffer.o dllist.o md5.o pqsignal.o fe-secure.o \ pqexpbuffer.o dllist.o md5.o pqsignal.o fe-secure.o \
wchar.o encnames.o \ wchar.o encnames.o \
v6util.o \
$(filter inet_aton.o snprintf.o strerror.o, $(LIBOBJS)) $(filter inet_aton.o snprintf.o strerror.o, $(LIBOBJS))

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-connect.c,v 1.214 2002/12/06 03:46:37 momjian Exp $ * $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-connect.c,v 1.215 2002/12/06 04:37:05 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -39,9 +39,6 @@
#include <arpa/inet.h> #include <arpa/inet.h>
#endif #endif
#include "libpq/v6util.h"
#ifndef HAVE_STRDUP #ifndef HAVE_STRDUP
#include "strdup.h" #include "strdup.h"
#endif #endif
@ -789,15 +786,6 @@ connectDBStart(PGconn *conn)
{ {
int portno, int portno,
family; family;
struct addrinfo* addrs = NULL;
struct addrinfo* addr_cur = NULL;
struct addrinfo hint;
const char* node = NULL;
const char* unix_node = "unix";
char portNoStr[64];
int ret;
int sockfd;
#ifdef USE_SSL #ifdef USE_SSL
StartupPacket np; /* Used to negotiate SSL connection */ StartupPacket np; /* Used to negotiate SSL connection */
@ -827,67 +815,101 @@ connectDBStart(PGconn *conn)
MemSet((char *) &conn->raddr, 0, sizeof(conn->raddr)); MemSet((char *) &conn->raddr, 0, sizeof(conn->raddr));
MemSet(&hint, 0, sizeof(hint)); if (conn->pghostaddr != NULL && conn->pghostaddr[0] != '\0')
hint.ai_socktype = SOCK_STREAM; {
if(conn->pghostaddr != NULL && conn->pghostaddr[0] != '\0'){ /* Using pghostaddr avoids a hostname lookup */
node = conn->pghostaddr; /* Note that this supports IPv4 only */
hint.ai_family = AF_UNSPEC; struct in_addr addr;
}
else if (conn->pghost != NULL && conn->pghost[0] != '\0'){
node = conn->pghost;
hint.ai_family = AF_UNSPEC;
}
#ifdef HAVE_UNIX_SOCKETS
else {
node = unix_node;
hint.ai_family = AF_UNIX;
}
#endif /* HAVE_UNIX_SOCKETS */
if (conn->pgport != NULL && conn->pgport[0] != '\0') if (!inet_aton(conn->pghostaddr, &addr))
portno = atoi(conn->pgport); {
printfPQExpBuffer(&conn->errorMessage,
libpq_gettext("invalid host address: %s\n"),
conn->pghostaddr);
goto connect_errReturn;
}
family = AF_INET;
memmove((char *) &(conn->raddr.in.sin_addr),
(char *) &addr, sizeof(addr));
}
else if (conn->pghost != NULL && conn->pghost[0] != '\0')
{
/* Using pghost, so we have to look-up the hostname */
struct hostent *hp;
hp = gethostbyname(conn->pghost);
if ((hp == NULL) || (hp->h_addrtype != AF_INET))
{
printfPQExpBuffer(&conn->errorMessage,
libpq_gettext("unknown host name: %s\n"),
conn->pghost);
goto connect_errReturn;
}
family = AF_INET;
memmove((char *) &(conn->raddr.in.sin_addr),
(char *) hp->h_addr,
hp->h_length);
}
else else
portno = DEF_PGPORT; {
/* pghostaddr and pghost are NULL, so use Unix domain socket */
if(hint.ai_family == AF_UNSPEC){ family = AF_UNIX;
snprintf(portNoStr, sizeof(portNoStr)/sizeof(char), }
"%d", portno);
/* Set family */
conn->raddr.sa.sa_family = family;
/* Set port number */
if (conn->pgport != NULL && conn->pgport[0] != '\0')
portno = atoi(conn->pgport);
else
portno = DEF_PGPORT;
if (family == AF_INET)
{
conn->raddr.in.sin_port = htons((unsigned short) (portno));
conn->raddr_len = sizeof(struct sockaddr_in);
} }
#ifdef HAVE_UNIX_SOCKETS #ifdef HAVE_UNIX_SOCKETS
else { else
UNIXSOCK_PATH(conn->raddr.un, portno, conn->pgunixsocket); {
conn->raddr_len = UNIXSOCK_LEN(conn->raddr.un); UNIXSOCK_PATH(conn->raddr.un, portno, conn->pgunixsocket);
strcpy(portNoStr, conn->raddr.un.sun_path); conn->raddr_len = UNIXSOCK_LEN(conn->raddr.un);
#ifdef USE_SSL #ifdef USE_SSL
/* Don't bother requesting SSL over a Unix socket */ /* Don't bother requesting SSL over a Unix socket */
conn->allow_ssl_try = false; conn->allow_ssl_try = false;
conn->require_ssl = false; conn->require_ssl = false;
#endif #endif
} }
#endif /* HAVE_UNIX_SOCKETS */ #endif
ret = getaddrinfo2(node, portNoStr, &hint, &addrs); /* Open a socket */
if(ret || addrs == NULL){ if ((conn->sock = socket(family, SOCK_STREAM, 0)) < 0)
printfPQExpBuffer(&conn->errorMessage, {
libpq_gettext("failed to getaddrinfo(): %s\n"), printfPQExpBuffer(&conn->errorMessage,
gai_strerror(ret) ); libpq_gettext("could not create socket: %s\n"),
goto connect_errReturn; SOCK_STRERROR(SOCK_ERRNO));
goto connect_errReturn;
} }
addr_cur = addrs;
do { /*
sockfd = socket(addr_cur->ai_family, addr_cur->ai_socktype, * Set the right options. Normally, we need nonblocking I/O, and we
addr_cur->ai_protocol); * don't want delay of outgoing data for AF_INET sockets. If we are
if(sockfd < 0){ * using SSL, then we need the blocking I/O (XXX Can this be fixed?).
continue; */
}
conn->sock = sockfd; if (family == AF_INET)
if (isAF_INETx2(addr_cur->ai_family) ){ {
if (!connectNoDelay(conn)) if (!connectNoDelay(conn))
goto connect_errReturn; goto connect_errReturn;
} }
#if !defined(USE_SSL) #if !defined(USE_SSL)
if (connectMakeNonblocking(conn) == 0) if (connectMakeNonblocking(conn) == 0)
goto connect_errReturn; goto connect_errReturn;
#endif #endif
/* ---------- /* ----------
@ -900,42 +922,31 @@ connectDBStart(PGconn *conn)
* ---------- * ----------
*/ */
retry1: retry1:
if(connect(sockfd, addr_cur->ai_addr, addr_cur->ai_addrlen) == 0){ if (connect(conn->sock, &conn->raddr.sa, conn->raddr_len) < 0)
/* We're connected already */ {
conn->status = CONNECTION_MADE;
break;
}
else {
if (SOCK_ERRNO == EINTR) if (SOCK_ERRNO == EINTR)
/* Interrupted system call - we'll just try again */ /* Interrupted system call - we'll just try again */
goto retry1; goto retry1;
if (SOCK_ERRNO == EINPROGRESS || SOCK_ERRNO == EWOULDBLOCK || SOCK_ERRNO == 0){ if (SOCK_ERRNO == EINPROGRESS || SOCK_ERRNO == EWOULDBLOCK || SOCK_ERRNO == 0)
{
/* /*
* This is fine - we're in non-blocking mode, and the * This is fine - we're in non-blocking mode, and the
* connection is in progress. * connection is in progress.
*/ */
conn->status = CONNECTION_STARTED; conn->status = CONNECTION_STARTED;
break; }
} else
} {
close(sockfd); /* Something's gone wrong */
} while( (addr_cur = addr_cur->ai_next) != NULL); connectFailureMessage(conn, SOCK_ERRNO);
goto connect_errReturn;
if(addr_cur == NULL){ }
printfPQExpBuffer(&conn->errorMessage,
libpq_gettext("could not create socket: %s\n"),
SOCK_STRERROR(SOCK_ERRNO));
goto connect_errReturn;
} }
else { else
family = addr_cur->ai_family; {
memmove(&conn->raddr, addr_cur->ai_addr, addr_cur->ai_addrlen); /* We're connected already */
conn->raddr_len = addr_cur->ai_addrlen; conn->status = CONNECTION_MADE;
freeaddrinfo2(hint.ai_family, addrs);
addrs = NULL;
} }
#ifdef USE_SSL #ifdef USE_SSL
@ -1027,9 +1038,7 @@ connect_errReturn:
conn->sock = -1; conn->sock = -1;
} }
conn->status = CONNECTION_BAD; conn->status = CONNECTION_BAD;
if(addrs != NULL){
freeaddrinfo2(hint.ai_family, addrs);
}
return 0; return 0;
} }