diff --git a/configure.in b/configure.in index fbc22aabbc..9dcea0ac46 100644 --- a/configure.in +++ b/configure.in @@ -1,5 +1,5 @@ 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 Developers, please strive to achieve this order: dnl @@ -1182,7 +1182,6 @@ AC_CONFIG_LINKS([ src/include/dynloader.h:src/backend/port/dynloader/${template}.h src/include/pg_config_os.h:src/include/port/${template}.h 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], diff --git a/src/backend/libpq/Makefile b/src/backend/libpq/Makefile index 6e7c1561b4..31eecf739b 100644 --- a/src/backend/libpq/Makefile +++ b/src/backend/libpq/Makefile @@ -4,7 +4,7 @@ # Makefile for libpq subsystem (backend half of libpq interface) # # 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 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 diff --git a/src/backend/libpq/auth.c b/src/backend/libpq/auth.c index dfd6d1e93f..a582ce723e 100644 --- a/src/backend/libpq/auth.c +++ b/src/backend/libpq/auth.c @@ -8,7 +8,7 @@ * * * 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"; - 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, "No pg_hba.conf entry for host %s, user %s, database %s", hostinfo, port->user, port->database); diff --git a/src/backend/libpq/hba.c b/src/backend/libpq/hba.c index 5cdf60da96..c468f2cb34 100644 --- a/src/backend/libpq/hba.c +++ b/src/backend/libpq/hba.c @@ -10,7 +10,7 @@ * * * 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) { - SockAddr file_ip_addr, mask; - + struct in_addr file_ip_addr, + mask; + if (strcmp(token, "hostssl") == 0) { #ifdef USE_SSL @@ -618,25 +619,16 @@ parse_hba(List *line, hbaPort *port, bool *found_p, bool *error_p) if (!line) goto hba_syntax; token = lfirst(line); - - if(SockAddr_pton(&file_ip_addr, token, strlen(token)) < 0){ - goto hba_syntax; - } + if (!inet_aton(token, &file_ip_addr)) + goto hba_syntax; /* Read the mask field. */ line = lnext(line); if (!line) goto hba_syntax; token = lfirst(line); - - if(SockAddr_pton(&mask, token, strlen(token)) < 0){ - goto hba_syntax; - } - - - if(file_ip_addr.sa.sa_family != mask.sa.sa_family){ - goto hba_syntax; - } + if (!inet_aton(token, &mask)) + goto hba_syntax; /* Read the rest of the line. */ line = lnext(line); @@ -647,7 +639,8 @@ parse_hba(List *line, hbaPort *port, bool *found_p, bool *error_p) goto hba_syntax; /* 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; } else diff --git a/src/backend/libpq/pg_hba.conf.sample b/src/backend/libpq/pg_hba.conf.sample index 1116debbc1..5338c79104 100644 --- a/src/backend/libpq/pg_hba.conf.sample +++ b/src/backend/libpq/pg_hba.conf.sample @@ -44,6 +44,5 @@ # TYPE DATABASE USER IP-ADDRESS IP-MASK METHOD -local all all trust -host all all 127.0.0.1 255.255.255.255 trust -host all all ::1 ffff:ffff:ffff:ffff:ffff:ffff trust +local all all trust +host all all 127.0.0.1 255.255.255.255 trust diff --git a/src/backend/libpq/pqcomm.c b/src/backend/libpq/pqcomm.c index 757a8a72ce..c3a95562b1 100644 --- a/src/backend/libpq/pqcomm.c +++ b/src/backend/libpq/pqcomm.c @@ -29,7 +29,7 @@ * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group * 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); 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, char *unixSocketName, int *fdP) { - int fd, - err; - int maxconn; - int one = 1; + SockAddr saddr; + int fd, + err; + int maxconn; + size_t len = 0; + int one = 1; - int ret; - struct addrinfo* addrs = NULL; - struct addrinfo hint; - char portNumberStr[64]; - char* service = portNumberStr; - char* hostn = (hostName[0] == '\0')? NULL : hostName; + Assert(family == AF_INET || family == AF_UNIX); - 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)); - hint.ai_family = family; - hint.ai_flags = AI_PASSIVE; - hint.ai_socktype = SOCK_STREAM; + if (family == AF_INET) + { + if ((setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *) &one, + sizeof(one))) == -1) + { + elog(LOG, "StreamServerPort: setsockopt(SO_REUSEADDR) failed: %m"); + return STATUS_ERROR; + } + } - snprintf(portNumberStr, sizeof(portNumberStr)/sizeof(char), - "%d", portNumber); + MemSet((char *) &saddr, 0, sizeof(saddr)); + saddr.sa.sa_family = family; #ifdef HAVE_UNIX_SOCKETS - if (family == AF_UNIX) { - if(StreamServerPortSubAFUNIX1(portNumber, unixSocketName) != STATUS_OK){ - return STATUS_ERROR; - } - service = sock_path; - } + if (family == AF_UNIX) + { + 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); + } #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); - if(ret || addrs == NULL){ - elog(LOG, "FATAL: StreamServerPort: getaddrinfo2() failed: %s\n", - gai_strerror(ret)); - freeaddrinfo2(hint.ai_family, addrs); - return STATUS_ERROR; - } + saddr.in.sin_port = htons(portNumber); + len = sizeof(struct sockaddr_in); + } - - /** YY DEBUG - if(addrs->ai_family == AF_UNIX){ - printf("%s-%s-%s \n", "debug: AF_UNIX!", unixSocketName, hostName); - } - else { - printf("%s", "debug: NOT AF_UNIX!\n"); - } - fflush(stdout); - **/ - - if( (fd = socket(addrs->ai_family, SOCK_STREAM, 0)) < 0){ - elog(LOG, "FATAL: StreamServerPort: socket() failed: %s\n", - strerror(errno)); - 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; - } + err = bind(fd, (struct sockaddr *) & saddr.sa, len); + if (err < 0) + { + if (family == AF_UNIX) + elog(LOG, "StreamServerPort: bind() failed: %m\n" + "\tIs another postmaster already running on port %d?\n" + "\tIf not, remove socket node (%s) and retry.", + (int) portNumber, sock_path); + else + elog(LOG, "StreamServerPort: bind() failed: %m\n" + "\tIs another postmaster already running on port %d?\n" + "\tIf not, wait a few seconds and retry.", + (int) portNumber); + return STATUS_ERROR; + } #ifdef HAVE_UNIX_SOCKETS - if (family == AF_UNIX){ - if(StreamServerPortSubAFUNIX2() != STATUS_OK){ - freeaddrinfo2(hint.ai_family, addrs); - return STATUS_ERROR; - } - } -#endif + if (family == AF_UNIX) + { + /* Arrange to unlink the socket file at exit */ + on_proc_exit(StreamDoUnlink, 0); - /* - * 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; + /* + * 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; - err = listen(fd, maxconn); - if (err < 0) { - elog(LOG, "FATAL: StreamServerPort: listen() failed: %s\n", - strerror(errno)); - freeaddrinfo2(hint.ai_family, addrs); - return STATUS_ERROR; - } + val = strtoul(Unix_socket_group, &endptr, 10); + if (*endptr == '\0') + { + /* numeric group id */ + gid = val; + } + else + { + /* convert group name to id */ + struct group *gr; - *fdP = fd; - freeaddrinfo2(hint.ai_family, addrs); - return STATUS_OK; - -} - -#ifdef HAVE_UNIX_SOCKETS -int StreamServerPortSubAFUNIX1(unsigned short portNumber, - char *unixSocketName ) -{ - SockAddr saddr; - int len; - - MemSet((char *) &saddr, 0, sizeof(saddr)); - - 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; -} + gr = getgrnam(Unix_socket_group); + if (!gr) + { + elog(LOG, "No such group as '%s'", + Unix_socket_group); + return STATUS_ERROR; + } + gid = gr->gr_gid; + } + if (chown(sock_path, -1, gid) == -1) + { + elog(LOG, "Could not set group of %s: %m", + sock_path); + return STATUS_ERROR; + } + } + 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 */ + /* + * 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 @@ -424,20 +391,8 @@ StreamConnection(int server_fd, Port *port) 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 */ - if ( isAF_INETx(&port->laddr) ) + if (port->laddr.sa.sa_family == AF_INET) { int on = 1; diff --git a/src/backend/libpq/v6util.c b/src/backend/libpq/v6util.c deleted file mode 100644 index 10bab95303..0000000000 --- a/src/backend/libpq/v6util.c +++ /dev/null @@ -1,300 +0,0 @@ -#include "postgres.h" - -#include -#include -#include -#include -#include -#include -#include -#ifdef HAVE_NETINET_TCP_H -#include -#endif -#include -#include - -#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); -} - - diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c index 0778784490..c1a25645a4 100644 --- a/src/backend/postmaster/postmaster.c +++ b/src/backend/postmaster/postmaster.c @@ -37,7 +37,7 @@ * * * 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 * @@ -669,7 +669,7 @@ PostmasterMain(int argc, char *argv[]) */ if (NetServer) { - status = StreamServerPort(AF_INET6, VirtualHost, + status = StreamServerPort(AF_INET, VirtualHost, (unsigned short) PostPortNumber, UnixSocketDir, &ServerSock_INET); @@ -2091,14 +2091,13 @@ DoBackend(Port *port) /* * 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; char *host_addr; - char ip_hostinfo[INET6_ADDRSTRLEN]; 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; diff --git a/src/include/libpq/libpq.h b/src/include/libpq/libpq.h index b0b1041be1..ced71326ce 100644 --- a/src/include/libpq/libpq.h +++ b/src/include/libpq/libpq.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group * 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 "libpq/libpq-be.h" -#include "libpq/v6util.h" /* ---------------- * PQArgBlock diff --git a/src/include/libpq/pqcomm.h b/src/include/libpq/pqcomm.h index a84978c570..1375852a0c 100644 --- a/src/include/libpq/pqcomm.h +++ b/src/include/libpq/pqcomm.h @@ -9,7 +9,7 @@ * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group * 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_in in; - struct sockaddr_in6 in6; struct sockaddr_un un; } SockAddr; diff --git a/src/include/libpq/v6util.h b/src/include/libpq/v6util.h deleted file mode 100644 index 6e325d17c0..0000000000 --- a/src/include/libpq/v6util.h +++ /dev/null @@ -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 */ diff --git a/src/interfaces/libpq/Makefile b/src/interfaces/libpq/Makefile index a91611cd30..f4e08f0a4b 100644 --- a/src/interfaces/libpq/Makefile +++ b/src/interfaces/libpq/Makefile @@ -4,7 +4,7 @@ # # 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 \ pqexpbuffer.o dllist.o md5.o pqsignal.o fe-secure.o \ wchar.o encnames.o \ - v6util.o \ $(filter inet_aton.o snprintf.o strerror.o, $(LIBOBJS)) diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c index 36782ecf70..3bf194fa7a 100644 --- a/src/interfaces/libpq/fe-connect.c +++ b/src/interfaces/libpq/fe-connect.c @@ -8,7 +8,7 @@ * * * 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 #endif -#include "libpq/v6util.h" - - #ifndef HAVE_STRDUP #include "strdup.h" #endif @@ -789,15 +786,6 @@ connectDBStart(PGconn *conn) { int portno, 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 StartupPacket np; /* Used to negotiate SSL connection */ @@ -827,67 +815,101 @@ connectDBStart(PGconn *conn) MemSet((char *) &conn->raddr, 0, sizeof(conn->raddr)); - MemSet(&hint, 0, sizeof(hint)); - hint.ai_socktype = SOCK_STREAM; - if(conn->pghostaddr != NULL && conn->pghostaddr[0] != '\0'){ - node = conn->pghostaddr; - hint.ai_family = AF_UNSPEC; - } - 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->pghostaddr != NULL && conn->pghostaddr[0] != '\0') + { + /* Using pghostaddr avoids a hostname lookup */ + /* Note that this supports IPv4 only */ + struct in_addr addr; - if (conn->pgport != NULL && conn->pgport[0] != '\0') - portno = atoi(conn->pgport); + if (!inet_aton(conn->pghostaddr, &addr)) + { + 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 - portno = DEF_PGPORT; - - if(hint.ai_family == AF_UNSPEC){ - snprintf(portNoStr, sizeof(portNoStr)/sizeof(char), - "%d", portno); + { + /* pghostaddr and pghost are NULL, so use Unix domain socket */ + family = AF_UNIX; + } + + /* 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 - else { - UNIXSOCK_PATH(conn->raddr.un, portno, conn->pgunixsocket); - conn->raddr_len = UNIXSOCK_LEN(conn->raddr.un); - strcpy(portNoStr, conn->raddr.un.sun_path); + else + { + UNIXSOCK_PATH(conn->raddr.un, portno, conn->pgunixsocket); + conn->raddr_len = UNIXSOCK_LEN(conn->raddr.un); #ifdef USE_SSL /* Don't bother requesting SSL over a Unix socket */ conn->allow_ssl_try = false; conn->require_ssl = false; #endif } -#endif /* HAVE_UNIX_SOCKETS */ +#endif - ret = getaddrinfo2(node, portNoStr, &hint, &addrs); - if(ret || addrs == NULL){ - printfPQExpBuffer(&conn->errorMessage, - libpq_gettext("failed to getaddrinfo(): %s\n"), - gai_strerror(ret) ); - goto connect_errReturn; + /* Open a socket */ + if ((conn->sock = socket(family, SOCK_STREAM, 0)) < 0) + { + printfPQExpBuffer(&conn->errorMessage, + libpq_gettext("could not create socket: %s\n"), + SOCK_STRERROR(SOCK_ERRNO)); + goto connect_errReturn; } - addr_cur = addrs; - do { - sockfd = socket(addr_cur->ai_family, addr_cur->ai_socktype, - addr_cur->ai_protocol); - if(sockfd < 0){ - continue; - } - conn->sock = sockfd; - if (isAF_INETx2(addr_cur->ai_family) ){ - if (!connectNoDelay(conn)) - goto connect_errReturn; - } + + /* + * Set the right options. Normally, we need nonblocking I/O, and we + * don't want delay of outgoing data for AF_INET sockets. If we are + * using SSL, then we need the blocking I/O (XXX Can this be fixed?). + */ + + if (family == AF_INET) + { + if (!connectNoDelay(conn)) + goto connect_errReturn; + } + #if !defined(USE_SSL) - if (connectMakeNonblocking(conn) == 0) - goto connect_errReturn; + if (connectMakeNonblocking(conn) == 0) + goto connect_errReturn; #endif /* ---------- @@ -900,42 +922,31 @@ connectDBStart(PGconn *conn) * ---------- */ retry1: - if(connect(sockfd, addr_cur->ai_addr, addr_cur->ai_addrlen) == 0){ - /* We're connected already */ - conn->status = CONNECTION_MADE; - break; - } - else { + if (connect(conn->sock, &conn->raddr.sa, conn->raddr_len) < 0) + { if (SOCK_ERRNO == EINTR) /* Interrupted system call - we'll just try again */ goto retry1; - if (SOCK_ERRNO == EINPROGRESS || SOCK_ERRNO == EWOULDBLOCK || SOCK_ERRNO == 0){ - - /* - * This is fine - we're in non-blocking mode, and the - * connection is in progress. - */ - conn->status = CONNECTION_STARTED; - break; - } - } - close(sockfd); - } while( (addr_cur = addr_cur->ai_next) != NULL); - - if(addr_cur == NULL){ - printfPQExpBuffer(&conn->errorMessage, - libpq_gettext("could not create socket: %s\n"), - SOCK_STRERROR(SOCK_ERRNO)); - - goto connect_errReturn; + if (SOCK_ERRNO == EINPROGRESS || SOCK_ERRNO == EWOULDBLOCK || SOCK_ERRNO == 0) + { + /* + * This is fine - we're in non-blocking mode, and the + * connection is in progress. + */ + conn->status = CONNECTION_STARTED; + } + else + { + /* Something's gone wrong */ + connectFailureMessage(conn, SOCK_ERRNO); + goto connect_errReturn; + } } - else { - family = addr_cur->ai_family; - memmove(&conn->raddr, addr_cur->ai_addr, addr_cur->ai_addrlen); - conn->raddr_len = addr_cur->ai_addrlen; - freeaddrinfo2(hint.ai_family, addrs); - addrs = NULL; + else + { + /* We're connected already */ + conn->status = CONNECTION_MADE; } #ifdef USE_SSL @@ -1027,9 +1038,7 @@ connect_errReturn: conn->sock = -1; } conn->status = CONNECTION_BAD; - if(addrs != NULL){ - freeaddrinfo2(hint.ai_family, addrs); - } + return 0; }