diff -cPr -x configure ../cvs-pgsql/configure.in ./configure.in *** ../cvs-pgsql/configure.in Fri Mar 21 18:18:34 2003 --- ./configure.in Wed Mar 26 02:15:14 2003 *************** *** 791,804 **** AC_CHECK_DECLS(fdatasync, [], [], [#include ]) ! # This exports HAVE_IPV6 to both C files and Makefiles ! AC_CHECK_FUNC(getaddrinfo, ! [AC_CHECK_TYPE(struct sockaddr_in6, ! [HAVE_IPV6="yes"; AC_DEFINE(HAVE_IPV6, 1)], ! [], [$ac_includes_default ! #include ])]) ! AC_SUBST(HAVE_IPV6) AC_CACHE_CHECK([for PS_STRINGS], [pgac_cv_var_PS_STRINGS], [AC_TRY_LINK( --- 791,802 ---- AC_CHECK_DECLS(fdatasync, [], [], [#include ]) ! AC_CHECK_TYPE([struct sockaddr_in6], ! [AC_CHECK_FUNC(inet_ntop, ! [AC_DEFINE(HAVE_IPV6, 1)])], ! [], [$ac_includes_default ! #include ]) AC_CACHE_CHECK([for PS_STRINGS], [pgac_cv_var_PS_STRINGS], [AC_TRY_LINK( *************** *** 849,855 **** AC_CHECK_FUNCS([fpclass fp_class fp_class_d class], [break]) fi ! AC_REPLACE_FUNCS([fseeko gethostname getopt_long getrusage inet_aton random srandom strcasecmp strdup strerror strtol strtoul]) # BSD/OS & NetBSD use a custom fseeko/ftello built on fsetpos/fgetpos # We override the previous test that said fseeko/ftello didn't exist --- 847,853 ---- AC_CHECK_FUNCS([fpclass fp_class fp_class_d class], [break]) fi ! AC_REPLACE_FUNCS([fseeko getaddrinfo gethostname getopt_long getrusage inet_aton random srandom strcasecmp strdup strerror strtol strtoul]) # BSD/OS & NetBSD use a custom fseeko/ftello built on fsetpos/fgetpos # We override the previous test that said fseeko/ftello didn't exist diff -cPr -x configure ../cvs-pgsql/src/Makefile.global.in ./src/Makefile.global.in *** ../cvs-pgsql/src/Makefile.global.in Mon Jan 6 19:53:36 2003 --- ./src/Makefile.global.in Wed Mar 26 02:04:50 2003 *************** *** 277,283 **** LDFLAGS += $(rpath) endif - HAVE_IPV6 = @HAVE_IPV6@ ########################################################################## # --- 277,282 ---- diff -cPr -x configure ../cvs-pgsql/src/backend/libpq/ip.c ./src/backend/libpq/ip.c *** ../cvs-pgsql/src/backend/libpq/ip.c Fri Jan 10 23:04:56 2003 --- ./src/backend/libpq/ip.c Wed Mar 26 02:04:50 2003 *************** *** 44,52 **** #define LOG stderr #endif ! #if defined(HAVE_UNIX_SOCKETS) && defined(HAVE_IPV6) static int getaddrinfo_unix(const char *path, const struct addrinfo *hintsp, ! struct addrinfo **result); #endif /* HAVE_UNIX_SOCKETS */ /* --- 44,52 ---- #define LOG stderr #endif ! #if defined(HAVE_UNIX_SOCKETS) static int getaddrinfo_unix(const char *path, const struct addrinfo *hintsp, ! struct addrinfo **result); #endif /* HAVE_UNIX_SOCKETS */ /* *************** *** 54,101 **** */ int getaddrinfo2(const char *hostname, const char *servname, - #ifdef HAVE_IPV6 const struct addrinfo *hintp, struct addrinfo **result) - #else - int family, SockAddr *result) - #endif { #ifdef HAVE_UNIX_SOCKETS - #ifdef HAVE_IPV6 if (hintp != NULL && hintp->ai_family == AF_UNIX) return getaddrinfo_unix(servname, hintp, result); - #else - if (family == AF_UNIX) - return 0; - #endif else { #endif /* HAVE_UNIX_SOCKETS */ - #ifdef HAVE_IPV6 /* NULL has special meaning to getaddrinfo */ return getaddrinfo((!hostname || hostname[0] == '\0') ? NULL : hostname, servname, hintp, result); - #else - if (hostname[0] == '\0') - result->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, "getaddrinfo2: gethostbyname(%s) failed\n", hostname); - return STATUS_ERROR; - } - memmove((char *) &(result->in.sin_addr), (char *) hp->h_addr, - hp->h_length); - } - - result->in.sin_port = htons((unsigned short)atoi(servname)); - return 0; - #endif /* HAVE_IPV6 */ - #ifdef HAVE_UNIX_SOCKETS } #endif /* HAVE_UNIX_SOCKETS */ --- 54,70 ---- *************** *** 105,111 **** /* * freeaddrinfo2 - free IPv6 addrinfo structures */ - #ifdef HAVE_IPV6 void freeaddrinfo2(int hint_ai_family, struct addrinfo *ai) { --- 74,79 ---- *************** *** 126,135 **** #endif /* HAVE_UNIX_SOCKETS */ freeaddrinfo(ai); } - #endif ! #if defined(HAVE_UNIX_SOCKETS) && defined(HAVE_IPV6) /* ------- * getaddrinfo_unix - get unix socket info using IPv6 * --- 94,102 ---- #endif /* HAVE_UNIX_SOCKETS */ freeaddrinfo(ai); } ! #if defined(HAVE_UNIX_SOCKETS) /* ------- * getaddrinfo_unix - get unix socket info using IPv6 * *************** *** 140,146 **** */ static int getaddrinfo_unix(const char *path, const struct addrinfo *hintsp, ! struct addrinfo **result) { struct addrinfo hints; struct addrinfo *aip; --- 107,113 ---- */ static int getaddrinfo_unix(const char *path, const struct addrinfo *hintsp, ! struct addrinfo **result) { struct addrinfo hints; struct addrinfo *aip; *************** *** 159,167 **** if (hints.ai_socktype == 0) hints.ai_socktype = SOCK_STREAM; ! if (!(hints.ai_family == AF_UNIX)) { ! elog(LOG, "hints.ai_family is invalied getaddrinfo_unix()\n"); return EAI_ADDRFAMILY; } --- 126,134 ---- if (hints.ai_socktype == 0) hints.ai_socktype = SOCK_STREAM; ! if (hints.ai_family != AF_UNIX) { ! elog(LOG, "hints.ai_family is invalid in getaddrinfo_unix()\n"); return EAI_ADDRFAMILY; } *************** *** 197,203 **** return 0; } ! #endif /* HAVE_UNIX_SOCKETS && HAVE_IPV6 */ /* ---------- * SockAddr_ntop - set IP address string from SockAddr --- 164,170 ---- return 0; } ! #endif /* HAVE_UNIX_SOCKETS */ /* ---------- * SockAddr_ntop - set IP address string from SockAddr diff -cPr -x configure ../cvs-pgsql/src/backend/libpq/pqcomm.c ./src/backend/libpq/pqcomm.c *** ../cvs-pgsql/src/backend/libpq/pqcomm.c Mon Jan 27 22:11:04 2003 --- ./src/backend/libpq/pqcomm.c Wed Mar 26 02:04:50 2003 *************** *** 96,108 **** static int Setup_AF_UNIX(void); #endif /* HAVE_UNIX_SOCKETS */ - #ifdef HAVE_IPV6 - #define FREEADDRINFO2(family, addrs) freeaddrinfo2((family), (addrs)) - #else - /* do nothing */ - #define FREEADDRINFO2(family, addrs) do {} while (0) - #endif - /* * Configuration options --- 96,101 ---- *************** *** 208,220 **** int ret; char portNumberStr[64]; char *service; - - /* - * IPv6 address lookups use a hint structure, while IPv4 creates an - * address structure directly. - */ - - #ifdef HAVE_IPV6 struct addrinfo *addrs = NULL; struct addrinfo hint; --- 201,206 ---- *************** *** 225,240 **** hint.ai_family = family; hint.ai_flags = AI_PASSIVE; hint.ai_socktype = SOCK_STREAM; - #else - SockAddr saddr; - size_t len; - - Assert(family == AF_INET || family == AF_UNIX); - - /* Initialize address structure */ - MemSet((char *) &saddr, 0, sizeof(saddr)); - saddr.sa.sa_family = family; - #endif /* HAVE_IPV6 */ #ifdef HAVE_UNIX_SOCKETS if (family == AF_UNIX) --- 211,216 ---- *************** *** 242,279 **** if (Lock_AF_UNIX(portNumber, unixSocketName) != STATUS_OK) return STATUS_ERROR; service = sock_path; - #ifndef HAVE_IPV6 - UNIXSOCK_PATH(saddr.un, portNumber, unixSocketName); - len = UNIXSOCK_LEN(saddr.un); - #endif } else #endif /* HAVE_UNIX_SOCKETS */ { snprintf(portNumberStr, sizeof(portNumberStr), "%d", portNumber); service = portNumberStr; - #ifndef HAVE_IPV6 - len = sizeof(saddr.in); - #endif } - /* Look up name using IPv6 or IPv4 routines */ - #ifdef HAVE_IPV6 ret = getaddrinfo2(hostName, service, &hint, &addrs); if (ret || addrs == NULL) - #else - ret = getaddrinfo2(hostName, service, family, &saddr); - if (ret) - #endif { elog(LOG, "server socket failure: getaddrinfo2()%s: %s", - #ifdef HAVE_IPV6 (family == AF_INET6) ? " using IPv6" : "", gai_strerror(ret)); if (addrs != NULL) ! FREEADDRINFO2(hint.ai_family, addrs); ! #else ! "", hostName); ! #endif return STATUS_ERROR; } --- 218,238 ---- if (Lock_AF_UNIX(portNumber, unixSocketName) != STATUS_OK) return STATUS_ERROR; service = sock_path; } else #endif /* HAVE_UNIX_SOCKETS */ { snprintf(portNumberStr, sizeof(portNumberStr), "%d", portNumber); service = portNumberStr; } ret = getaddrinfo2(hostName, service, &hint, &addrs); if (ret || addrs == NULL) { elog(LOG, "server socket failure: getaddrinfo2()%s: %s", (family == AF_INET6) ? " using IPv6" : "", gai_strerror(ret)); if (addrs != NULL) ! freeaddrinfo2(hint.ai_family, addrs); return STATUS_ERROR; } *************** *** 281,287 **** { elog(LOG, "server socket failure: socket(): %s", strerror(errno)); ! FREEADDRINFO2(hint.ai_family, addrs); return STATUS_ERROR; } --- 240,246 ---- { elog(LOG, "server socket failure: socket(): %s", strerror(errno)); ! freeaddrinfo2(hint.ai_family, addrs); return STATUS_ERROR; } *************** *** 292,308 **** { elog(LOG, "server socket failure: setsockopt(SO_REUSEADDR): %s", strerror(errno)); ! FREEADDRINFO2(hint.ai_family, addrs); return STATUS_ERROR; } } - #ifdef HAVE_IPV6 Assert(addrs->ai_next == NULL && addrs->ai_family == family); err = bind(fd, addrs->ai_addr, addrs->ai_addrlen); - #else - err = bind(fd, (struct sockaddr *) &saddr.sa, len); - #endif if (err < 0) { elog(LOG, "server socket failure: bind(): %s\n" --- 251,263 ---- { elog(LOG, "server socket failure: setsockopt(SO_REUSEADDR): %s", strerror(errno)); ! freeaddrinfo2(hint.ai_family, addrs); return STATUS_ERROR; } } Assert(addrs->ai_next == NULL && addrs->ai_family == family); err = bind(fd, addrs->ai_addr, addrs->ai_addrlen); if (err < 0) { elog(LOG, "server socket failure: bind(): %s\n" *************** *** 313,319 **** sock_path); else elog(LOG, "\tIf not, wait a few seconds and retry."); ! FREEADDRINFO2(hint.ai_family, addrs); return STATUS_ERROR; } --- 268,274 ---- sock_path); else elog(LOG, "\tIf not, wait a few seconds and retry."); ! freeaddrinfo2(hint.ai_family, addrs); return STATUS_ERROR; } *************** *** 322,328 **** { if (Setup_AF_UNIX() != STATUS_OK) { ! FREEADDRINFO2(hint.ai_family, addrs); return STATUS_ERROR; } } --- 277,283 ---- { if (Setup_AF_UNIX() != STATUS_OK) { ! freeaddrinfo2(hint.ai_family, addrs); return STATUS_ERROR; } } *************** *** 342,353 **** { elog(LOG, "server socket failure: listen(): %s", strerror(errno)); ! FREEADDRINFO2(hint.ai_family, addrs); return STATUS_ERROR; } *fdP = fd; ! FREEADDRINFO2(hint.ai_family, addrs); return STATUS_OK; } --- 297,308 ---- { elog(LOG, "server socket failure: listen(): %s", strerror(errno)); ! freeaddrinfo2(hint.ai_family, addrs); return STATUS_ERROR; } *fdP = fd; ! freeaddrinfo2(hint.ai_family, addrs); return STATUS_OK; } diff -cPr -x configure ../cvs-pgsql/src/include/getaddrinfo.h ./src/include/getaddrinfo.h *** ../cvs-pgsql/src/include/getaddrinfo.h Thu Jan 1 01:00:00 1970 --- ./src/include/getaddrinfo.h Wed Mar 26 02:04:50 2003 *************** *** 0 **** --- 1,43 ---- + /* $Header$ */ + + #ifndef GETADDRINFO_H + #define GETADDRINFO_H + + #include "c.h" + #include + + + struct addrinfo { + int ai_flags; + int ai_family; + int ai_socktype; + int ai_protocol; + size_t ai_addrlen; + struct sockaddr *ai_addr; + char *ai_canonname; + struct addrinfo *ai_next; + }; + + + int getaddrinfo(const char *node, const char *service, + const struct addrinfo *hints, struct addrinfo **res); + void freeaddrinfo(struct addrinfo *res); + const char *gai_strerror(int errcode); + + + #define EAI_BADFLAGS -1 + #define EAI_NONAME -2 + #define EAI_AGAIN -3 + #define EAI_FAIL -4 + #define EAI_NODATA -5 + #define EAI_FAMILY -6 + #define EAI_SOCKTYPE -7 + #define EAI_SERVICE -8 + #define EAI_ADDRFAMILY -9 + #define EAI_MEMORY -10 + #define EAI_SYSTEM -11 + + #define AI_PASSIVE 0x0001 + #define AI_NUMERICHOST 0x0004 + + #endif /* GETADDRINFO_H */ diff -cPr -x configure ../cvs-pgsql/src/include/libpq/ip.h ./src/include/libpq/ip.h *** ../cvs-pgsql/src/include/libpq/ip.h Mon Jan 6 04:18:28 2003 --- ./src/include/libpq/ip.h Wed Mar 26 02:04:50 2003 *************** *** 1,17 **** #ifndef IP_H #define IP_H #include #include #include "libpq/pqcomm.h" - #ifdef HAVE_IPV6 - void freeaddrinfo2(int hint_ai_family, struct addrinfo *ai); int getaddrinfo2(const char *hostname, const char *servname, ! const struct addrinfo *hintp, struct addrinfo **result); ! #else ! int getaddrinfo2(const char *hostname, const char *servname, ! int family, SockAddr *result); ! #endif char *SockAddr_ntop(const SockAddr *sa, char *dst, size_t cnt, int v4conv); int SockAddr_pton(SockAddr *sa, const char *src); --- 1,16 ---- #ifndef IP_H #define IP_H + #include "c.h" #include #include #include "libpq/pqcomm.h" + #ifndef HAVE_GETADDRINFO + #include "getaddrinfo.h" + #endif int getaddrinfo2(const char *hostname, const char *servname, ! const struct addrinfo *hintp, struct addrinfo **result); ! void freeaddrinfo2(int hint_ai_family, struct addrinfo *ai); char *SockAddr_ntop(const SockAddr *sa, char *dst, size_t cnt, int v4conv); int SockAddr_pton(SockAddr *sa, const char *src); diff -cPr -x configure ../cvs-pgsql/src/include/pg_config.h.in ./src/include/pg_config.h.in *** ../cvs-pgsql/src/include/pg_config.h.in Wed Mar 12 16:46:12 2003 --- ./src/include/pg_config.h.in Wed Mar 26 02:04:50 2003 *************** *** 459,464 **** --- 459,467 ---- #undef HAVE_FP_CLASS_D #undef HAVE_CLASS + /* Set to 1 if you have getaddrinfo() */ + #undef HAVE_GETADDRINFO + /* Set to 1 if you have gethostname() */ #undef HAVE_GETHOSTNAME diff -cPr -x configure ../cvs-pgsql/src/interfaces/libpq/Makefile ./src/interfaces/libpq/Makefile *** ../cvs-pgsql/src/interfaces/libpq/Makefile Mon Feb 10 20:02:48 2003 --- ./src/interfaces/libpq/Makefile Wed Mar 26 02:42:02 2003 *************** *** 23,29 **** OBJS= fe-auth.o fe-connect.o fe-exec.o fe-misc.o fe-print.o fe-lobj.o \ pqexpbuffer.o dllist.o pqsignal.o fe-secure.o wchar.o encnames.o ip.o \ md5.o \ ! $(filter inet_aton.o snprintf.o strerror.o, $(LIBOBJS)) # Add libraries that libpq depends (or might depend) on into the --- 23,29 ---- OBJS= fe-auth.o fe-connect.o fe-exec.o fe-misc.o fe-print.o fe-lobj.o \ pqexpbuffer.o dllist.o pqsignal.o fe-secure.o wchar.o encnames.o ip.o \ md5.o \ ! $(filter getaddrinfo.o inet_aton.o snprintf.o strerror.o, $(LIBOBJS)) # Add libraries that libpq depends (or might depend) on into the *************** *** 54,60 **** # symlink the source files in here and build our own object file. # this only gets done if configure finds system doesn't have inet_aton() ! inet_aton.c snprintf.c strerror.c: %.c : $(top_srcdir)/src/port/%.c rm -f $@ && $(LN_S) $< . encnames.c wchar.c : % : $(backend_src)/utils/mb/% --- 54,60 ---- # symlink the source files in here and build our own object file. # this only gets done if configure finds system doesn't have inet_aton() ! getaddrinfo.c inet_aton.c snprintf.c strerror.c: %.c : $(top_srcdir)/src/port/%.c rm -f $@ && $(LN_S) $< . encnames.c wchar.c : % : $(backend_src)/utils/mb/% *************** *** 75,78 **** clean distclean maintainer-clean: clean-lib rm -f $(OBJS) dllist.c md5.c ip.c wchar.c encnames.c ! rm -f $(OBJS) inet_aton.c snprintf.c strerror.c --- 75,78 ---- clean distclean maintainer-clean: clean-lib rm -f $(OBJS) dllist.c md5.c ip.c wchar.c encnames.c ! rm -f $(OBJS) getaddrinfo.c inet_aton.c snprintf.c strerror.c diff -cPr -x configure ../cvs-pgsql/src/interfaces/libpq/fe-connect.c ./src/interfaces/libpq/fe-connect.c *** ../cvs-pgsql/src/interfaces/libpq/fe-connect.c Fri Mar 21 18:03:38 2003 --- ./src/interfaces/libpq/fe-connect.c Wed Mar 26 02:04:50 2003 *************** *** 50,62 **** #include "mb/pg_wchar.h" - #ifdef HAVE_IPV6 - #define FREEADDRINFO2(family, addrs) freeaddrinfo2((family), (addrs)) - #else - /* do nothing */ - #define FREEADDRINFO2(family, addrs) do {} while (0) - #endif - #ifdef WIN32 static int inet_aton(const char *cp, struct in_addr * inp) --- 50,55 ---- *************** *** 803,809 **** StartupPacket np; /* Used to negotiate SSL connection */ char SSLok; #endif - #ifdef HAVE_IPV6 struct addrinfo *addrs = NULL; struct addrinfo *addr_cur = NULL; struct addrinfo hint; --- 796,801 ---- *************** *** 814,822 **** /* Initialize hint structure */ MemSet(&hint, 0, sizeof(hint)); hint.ai_socktype = SOCK_STREAM; - #else - int family = -1; - #endif if (!conn) return 0; --- 806,811 ---- *************** *** 835,845 **** /* * Set up the connection to postmaster/backend. - * - * This code is confusing because IPv6 creates a hint structure - * that is passed to getaddrinfo2(), which returns a list of address - * structures that are looped through, while IPv4 creates an address - * structure directly. */ MemSet((char *) &conn->raddr, 0, sizeof(conn->raddr)); --- 824,829 ---- *************** *** 853,925 **** if (conn->pghostaddr != NULL && conn->pghostaddr[0] != '\0') { ! #ifdef HAVE_IPV6 node = conn->pghostaddr; hint.ai_family = AF_UNSPEC; ! #else ! /* Using pghostaddr avoids a hostname lookup */ ! struct in_addr addr; ! ! if (!inet_aton(conn->pghostaddr, &addr)) ! { ! printfPQExpBuffer(&conn->errorMessage, ! libpq_gettext("invalid host address: %s\n"), ! conn->pghostaddr); ! goto connect_errReturn; ! } ! ! family = AF_INET; ! ! memcpy((char *) &(conn->raddr.in.sin_addr), ! (char *) &addr, sizeof(addr)); ! #endif } else if (conn->pghost != NULL && conn->pghost[0] != '\0') { ! #ifdef HAVE_IPV6 node = conn->pghost; hint.ai_family = AF_UNSPEC; - #else - /* Using pghost, so we have to look-up the hostname */ - if (getaddrinfo2(conn->pghost, portstr, family, &conn->raddr) != 0) - goto connect_errReturn; - - family = AF_INET; - #endif } else { #ifdef HAVE_UNIX_SOCKETS - #ifdef HAVE_IPV6 node = unix_node; hint.ai_family = AF_UNIX; - #else - /* pghostaddr and pghost are NULL, so use Unix domain socket */ - family = AF_UNIX; - #endif - #endif /* HAVE_UNIX_SOCKETS */ - } - - #ifndef HAVE_IPV6 - /* Set family */ - conn->raddr.sa.sa_family = family; - #endif - - #ifdef HAVE_IPV6 - if (hint.ai_family == AF_UNSPEC) - { - /* do nothing */ - } - #else - if (family == AF_INET) - { - conn->raddr.in.sin_port = htons((unsigned short) (portnum)); - conn->raddr_len = sizeof(struct sockaddr_in); - } - #endif - else - { - #ifdef HAVE_UNIX_SOCKETS UNIXSOCK_PATH(conn->raddr.un, portnum, conn->pgunixsocket); conn->raddr_len = UNIXSOCK_LEN(conn->raddr.un); StrNCpy(portstr, conn->raddr.un.sun_path, sizeof(portstr)); --- 837,859 ---- if (conn->pghostaddr != NULL && conn->pghostaddr[0] != '\0') { ! /* Using pghostaddr avoids a hostname lookup */ node = conn->pghostaddr; hint.ai_family = AF_UNSPEC; ! hint.ai_flags = AI_NUMERICHOST; } else if (conn->pghost != NULL && conn->pghost[0] != '\0') { ! /* Using pghost, so we have to look-up the hostname */ node = conn->pghost; hint.ai_family = AF_UNSPEC; } else { + /* pghostaddr and pghost are NULL, so use Unix domain socket */ #ifdef HAVE_UNIX_SOCKETS node = unix_node; hint.ai_family = AF_UNIX; UNIXSOCK_PATH(conn->raddr.un, portnum, conn->pgunixsocket); conn->raddr_len = UNIXSOCK_LEN(conn->raddr.un); StrNCpy(portstr, conn->raddr.un.sun_path, sizeof(portstr)); *************** *** 931,937 **** #endif /* HAVE_UNIX_SOCKETS */ } - #ifdef HAVE_IPV6 /* Use getaddrinfo2() to resolve the address */ ret = getaddrinfo2(node, portstr, &hint, &addrs); if (ret || addrs == NULL) --- 865,870 ---- *************** *** 941,980 **** gai_strerror(ret)); goto connect_errReturn; } - #endif /* ! * For IPV6 we loop over the possible addresses returned by ! * getaddrinfo2(), and fail only when they all fail (reporting the ! * error returned for the *last* alternative, which may not be what ! * users expect :-(). Otherwise, there is no true loop here. * * In either case, we never actually fall out of the loop; the * only exits are via "break" or "goto connect_errReturn". Thus, * there is no exit test in the for(). */ ! for ( ! #ifdef HAVE_IPV6 ! addr_cur = addrs; ; addr_cur = addr_cur->ai_next ! #else ! ;; ! #endif ! ) { /* Open a socket */ - #ifdef HAVE_IPV6 conn->sock = socket(addr_cur->ai_family, SOCK_STREAM, addr_cur->ai_protocol); - #else - conn->sock = socket(family, SOCK_STREAM, 0); - #endif if (conn->sock < 0) { - #ifdef HAVE_IPV6 /* ignore socket() failure if we have more addrs to try */ if (addr_cur->ai_next != NULL) continue; - #endif printfPQExpBuffer(&conn->errorMessage, libpq_gettext("could not create socket: %s\n"), SOCK_STRERROR(SOCK_ERRNO)); --- 874,900 ---- gai_strerror(ret)); goto connect_errReturn; } /* ! * We loop over the possible addresses returned by getaddrinfo2(), ! * and fail only when they all fail (reporting the error returned ! * for the *last* alternative, which may not be what users expect ! * :-(). * * In either case, we never actually fall out of the loop; the * only exits are via "break" or "goto connect_errReturn". Thus, * there is no exit test in the for(). */ ! for (addr_cur = addrs; ; addr_cur = addr_cur->ai_next) { /* Open a socket */ conn->sock = socket(addr_cur->ai_family, SOCK_STREAM, addr_cur->ai_protocol); if (conn->sock < 0) { /* ignore socket() failure if we have more addrs to try */ if (addr_cur->ai_next != NULL) continue; printfPQExpBuffer(&conn->errorMessage, libpq_gettext("could not create socket: %s\n"), SOCK_STRERROR(SOCK_ERRNO)); *************** *** 987,997 **** * using SSL, then we need the blocking I/O (XXX Can this be fixed?). */ - #ifdef HAVE_IPV6 if (isAF_INETx(addr_cur->ai_family)) - #else - if (isAF_INETx(family)) - #endif { if (!connectNoDelay(conn)) goto connect_errReturn; --- 907,913 ---- *************** *** 1012,1022 **** * ---------- */ retry1: - #ifdef HAVE_IPV6 if (connect(conn->sock, addr_cur->ai_addr, addr_cur->ai_addrlen) < 0) - #else - if (connect(conn->sock, &conn->raddr.sa, conn->raddr_len) < 0) - #endif { if (SOCK_ERRNO == EINTR) /* Interrupted system call - we'll just try again */ --- 928,934 ---- *************** *** 1043,1049 **** * This connection failed. We need to close the socket, * and either loop to try the next address or report an error. */ - #ifdef HAVE_IPV6 /* ignore connect() failure if we have more addrs to try */ if (addr_cur->ai_next != NULL) { --- 955,960 ---- *************** *** 1051,1069 **** conn->sock = -1; continue; } ! #endif connectFailureMessage(conn, SOCK_ERRNO); goto connect_errReturn; } /* loop over addrs */ - #ifdef HAVE_IPV6 /* Remember the successfully opened address alternative */ memcpy(&conn->raddr, addr_cur->ai_addr, addr_cur->ai_addrlen); conn->raddr_len = addr_cur->ai_addrlen; /* and release the address list */ ! FREEADDRINFO2(hint.ai_family, addrs); addrs = NULL; - #endif #ifdef USE_SSL /* Attempt to negotiate SSL usage */ --- 962,980 ---- conn->sock = -1; continue; } ! /* copy failed address for error report */ ! memcpy(&conn->raddr, addr_cur->ai_addr, addr_cur->ai_addrlen); ! conn->raddr_len = addr_cur->ai_addrlen; connectFailureMessage(conn, SOCK_ERRNO); goto connect_errReturn; } /* loop over addrs */ /* Remember the successfully opened address alternative */ memcpy(&conn->raddr, addr_cur->ai_addr, addr_cur->ai_addrlen); conn->raddr_len = addr_cur->ai_addrlen; /* and release the address list */ ! freeaddrinfo2(hint.ai_family, addrs); addrs = NULL; #ifdef USE_SSL /* Attempt to negotiate SSL usage */ *************** *** 1153,1162 **** conn->sock = -1; } conn->status = CONNECTION_BAD; - #ifdef HAVE_IPV6 if (addrs != NULL) ! FREEADDRINFO2(hint.ai_family, addrs); ! #endif return 0; } --- 1064,1071 ---- conn->sock = -1; } conn->status = CONNECTION_BAD; if (addrs != NULL) ! freeaddrinfo2(hint.ai_family, addrs); return 0; } diff -cPr -x configure ../cvs-pgsql/src/port/getaddrinfo.c ./src/port/getaddrinfo.c *** ../cvs-pgsql/src/port/getaddrinfo.c Thu Jan 1 01:00:00 1970 --- ./src/port/getaddrinfo.c Wed Mar 26 02:08:24 2003 *************** *** 0 **** --- 1,132 ---- + /* $Header$ */ + + #include "c.h" + #include "getaddrinfo.h" + #include + #include + #include + #include + + + int + getaddrinfo(const char *node, const char *service, + const struct addrinfo *hints, + struct addrinfo **res) + { + struct addrinfo *ai; + struct sockaddr_in sin, *psin; + + if (!hints || (hints->ai_family != AF_INET && hints->ai_family != AF_UNSPEC)) + return EAI_FAMILY; + + if (hints->ai_socktype != SOCK_STREAM) + return EAI_SOCKTYPE; + + if (!node && !service) + return EAI_NONAME; + + if (node) + { + if (node[0] == '\0') + sin.sin_addr.s_addr = htonl(INADDR_ANY); + else if (hints->ai_flags & AI_NUMERICHOST) + { + inet_aton(node, &sin.sin_addr); + } + else + { + struct hostent *hp; + + hp = gethostbyname(node); + if (hp == NULL) + { + switch (h_errno) + { + case HOST_NOT_FOUND: + return EAI_NONAME; + case NO_DATA: + return EAI_NODATA; + case TRY_AGAIN: + return EAI_AGAIN; + case NO_RECOVERY: + default: + return EAI_FAIL; + } + } + if (hp->h_addrtype != AF_INET) + return EAI_ADDRFAMILY; + + memmove(&(sin.sin_addr), hp->h_addr, hp->h_length); + } + } + else + { + if (hints->ai_flags & AI_PASSIVE) + sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + } + + if (service) + sin.sin_port = htons((unsigned short)atoi(service)); + + ai = malloc(sizeof(*ai)); + if (!ai) + return EAI_MEMORY; + psin = malloc(sizeof(*psin)); + if (!psin) + { + free(ai); + return EAI_MEMORY; + } + + memcpy(psin, &sin, sizeof(sin)); + + ai->ai_family = hints->ai_family; + ai->ai_socktype = hints->ai_socktype; + ai->ai_protocol = hints->ai_protocol; + ai->ai_addrlen = sizeof(*psin); + ai->ai_addr = (struct sockaddr *) psin; + ai->ai_canonname = NULL; + ai->ai_next = NULL; + + *res = ai; + + return 0; + } + + + void + freeaddrinfo(struct addrinfo *res) + { + if (res) + { + if (res->ai_addr) + free(res->ai_addr); + free(res); + } + } + + + const char* + gai_strerror(int errcode) + { + int hcode; + + switch (errcode) + { + case EAI_NONAME: + hcode = HOST_NOT_FOUND; + break; + case EAI_NODATA: + hcode = NO_DATA; + break; + case EAI_AGAIN: + hcode = TRY_AGAIN; + break; + case EAI_FAIL: + default: + hcode = NO_RECOVERY; + break; + } + + return hstrerror(hcode); + }