diff --git a/config/c-library.m4 b/config/c-library.m4 index d301b0155cf..d6acd8c98b6 100644 --- a/config/c-library.m4 +++ b/config/c-library.m4 @@ -1,5 +1,5 @@ # Macros that test various C library quirks -# $Header: /cvsroot/pgsql/config/c-library.m4,v 1.22 2003/06/23 23:51:59 momjian Exp $ +# $Header: /cvsroot/pgsql/config/c-library.m4,v 1.23 2003/07/23 23:30:39 tgl Exp $ # PGAC_VAR_INT_TIMEZONE @@ -100,8 +100,8 @@ AC_DEFUN([PGAC_STRUCT_SOCKADDR_UN], # PGAC_STRUCT_SOCKADDR_STORAGE # ---------------------------- -# If `struct sockaddr_storage' exists, define HAVE_STRUCT_SOCKADDR_STORAGE. If -# it is missing then one could define it. +# If `struct sockaddr_storage' exists, define HAVE_STRUCT_SOCKADDR_STORAGE. +# If it is missing then one could define it. AC_DEFUN([PGAC_STRUCT_SOCKADDR_STORAGE], [AC_CHECK_TYPES([struct sockaddr_storage], [], [], [#include @@ -110,18 +110,24 @@ AC_DEFUN([PGAC_STRUCT_SOCKADDR_STORAGE], #endif ])])# PGAC_STRUCT_SOCKADDR_STORAGE -# PGAC_STRUCT_SOCKADDR_STORAGE_SS_FAMILY +# PGAC_STRUCT_SOCKADDR_STORAGE_MEMBERS # -------------------------------------- -# This checks if the struct sockaddr has a proper ss_family and not an -# __ss_family as rfc2553 defined. -AC_DEFUN([PGAC_STRUCT_SOCKADDR_STORAGE_SS_FAMILY], +# Check the members of `struct sockaddr_storage'. We need to know about +# ss_family and ss_len. (Some platforms follow RFC 2553 and call them +# __ss_family and __ss_len.) We also check struct sockaddr's sa_len; +# if we have to define our own `struct sockaddr_storage', this tells us +# whether we need to provide an ss_len field. +AC_DEFUN([PGAC_STRUCT_SOCKADDR_STORAGE_MEMBERS], [AC_CHECK_MEMBERS([struct sockaddr_storage.ss_family, - struct sockaddr_storage.__ss_family], [], [], + struct sockaddr_storage.__ss_family, + struct sockaddr_storage.ss_len, + struct sockaddr_storage.__ss_len, + struct sockaddr.sa_len], [], [], [#include #ifdef HAVE_SYS_SOCKET_H #include #endif -])])# PGAC_STRUCT_SOCKADDR_STORAGE_SS_FAMILY +])])# PGAC_STRUCT_SOCKADDR_STORAGE_MEMBERS # PGAC_STRUCT_ADDRINFO diff --git a/configure b/configure index 99bce0c0410..24066b6fac3 100755 --- a/configure +++ b/configure @@ -9990,6 +9990,186 @@ cat >>confdefs.h <<_ACEOF _ACEOF +fi +echo "$as_me:$LINENO: checking for struct sockaddr_storage.ss_len" >&5 +echo $ECHO_N "checking for struct sockaddr_storage.ss_len... $ECHO_C" >&6 +if test "${ac_cv_member_struct_sockaddr_storage_ss_len+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +#include +#ifdef HAVE_SYS_SOCKET_H +#include +#endif + + +#ifdef F77_DUMMY_MAIN +# ifdef __cplusplus + extern "C" +# endif + int F77_DUMMY_MAIN() { return 1; } +#endif +int +main () +{ +static struct sockaddr_storage ac_aggr; +if (ac_aggr.ss_len) +return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_member_struct_sockaddr_storage_ss_len=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_member_struct_sockaddr_storage_ss_len=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_member_struct_sockaddr_storage_ss_len" >&5 +echo "${ECHO_T}$ac_cv_member_struct_sockaddr_storage_ss_len" >&6 +if test $ac_cv_member_struct_sockaddr_storage_ss_len = yes; then + +cat >>confdefs.h <<_ACEOF +#define HAVE_STRUCT_SOCKADDR_STORAGE_SS_LEN 1 +_ACEOF + + +fi +echo "$as_me:$LINENO: checking for struct sockaddr_storage.__ss_len" >&5 +echo $ECHO_N "checking for struct sockaddr_storage.__ss_len... $ECHO_C" >&6 +if test "${ac_cv_member_struct_sockaddr_storage___ss_len+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +#include +#ifdef HAVE_SYS_SOCKET_H +#include +#endif + + +#ifdef F77_DUMMY_MAIN +# ifdef __cplusplus + extern "C" +# endif + int F77_DUMMY_MAIN() { return 1; } +#endif +int +main () +{ +static struct sockaddr_storage ac_aggr; +if (ac_aggr.__ss_len) +return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_member_struct_sockaddr_storage___ss_len=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_member_struct_sockaddr_storage___ss_len=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_member_struct_sockaddr_storage___ss_len" >&5 +echo "${ECHO_T}$ac_cv_member_struct_sockaddr_storage___ss_len" >&6 +if test $ac_cv_member_struct_sockaddr_storage___ss_len = yes; then + +cat >>confdefs.h <<_ACEOF +#define HAVE_STRUCT_SOCKADDR_STORAGE___SS_LEN 1 +_ACEOF + + +fi +echo "$as_me:$LINENO: checking for struct sockaddr.sa_len" >&5 +echo $ECHO_N "checking for struct sockaddr.sa_len... $ECHO_C" >&6 +if test "${ac_cv_member_struct_sockaddr_sa_len+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +#include +#ifdef HAVE_SYS_SOCKET_H +#include +#endif + + +#ifdef F77_DUMMY_MAIN +# ifdef __cplusplus + extern "C" +# endif + int F77_DUMMY_MAIN() { return 1; } +#endif +int +main () +{ +static struct sockaddr ac_aggr; +if (ac_aggr.sa_len) +return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_member_struct_sockaddr_sa_len=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_member_struct_sockaddr_sa_len=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_member_struct_sockaddr_sa_len" >&5 +echo "${ECHO_T}$ac_cv_member_struct_sockaddr_sa_len" >&6 +if test $ac_cv_member_struct_sockaddr_sa_len = yes; then + +cat >>confdefs.h <<_ACEOF +#define HAVE_STRUCT_SOCKADDR_SA_LEN 1 +_ACEOF + + fi echo "$as_me:$LINENO: checking for struct addrinfo" >&5 diff --git a/configure.in b/configure.in index 515d53c183a..d189a5ffdb3 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.269 2003/07/23 17:27:28 momjian Exp $ +dnl $Header: /cvsroot/pgsql/configure.in,v 1.270 2003/07/23 23:30:40 tgl Exp $ dnl dnl Developers, please strive to achieve this order: dnl @@ -778,7 +778,7 @@ PGAC_STRUCT_TIMEZONE PGAC_UNION_SEMUN PGAC_STRUCT_SOCKADDR_UN PGAC_STRUCT_SOCKADDR_STORAGE -PGAC_STRUCT_SOCKADDR_STORAGE_SS_FAMILY +PGAC_STRUCT_SOCKADDR_STORAGE_MEMBERS PGAC_STRUCT_ADDRINFO AC_CHECK_TYPES([struct cmsgcred, struct fcred, struct sockcred], [], [], diff --git a/src/backend/libpq/auth.c b/src/backend/libpq/auth.c index ca6bfcf4d7e..a24f0978466 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.104 2003/07/22 19:00:10 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/libpq/auth.c,v 1.105 2003/07/23 23:30:40 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -434,11 +434,10 @@ ClientAuthentication(Port *port) { char hostinfo[NI_MAXHOST]; - getnameinfo((struct sockaddr *) &port->raddr.addr, - port->raddr.salen, - hostinfo, sizeof(hostinfo), - NULL, 0, - NI_NUMERICHOST); + getnameinfo_all(&port->raddr.addr, port->raddr.salen, + hostinfo, sizeof(hostinfo), + NULL, 0, + NI_NUMERICHOST); ereport(FATAL, (errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION), diff --git a/src/backend/libpq/hba.c b/src/backend/libpq/hba.c index f0bd0b85154..0d98e729a40 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.106 2003/07/22 21:19:22 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/libpq/hba.c,v 1.107 2003/07/23 23:30:40 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -648,31 +648,33 @@ parse_hba(List *line, hbaPort *port, bool *found_p, bool *error_p) hints.ai_next = NULL; /* Get the IP address either way */ - ret = getaddrinfo2(token, NULL, &hints, &file_ip_addr); + ret = getaddrinfo_all(token, NULL, &hints, &file_ip_addr); if (ret || !file_ip_addr) { ereport(LOG, (errcode(ERRCODE_CONFIG_FILE_ERROR), - errmsg("failed to interpret IP address \"%s\" in config file: %s", + errmsg("could not interpret IP address \"%s\" in config file: %s", token, gai_strerror(ret)))); if (cidr_slash) *cidr_slash = '/'; goto hba_syntax; } + if (cidr_slash) + *cidr_slash = '/'; + if (file_ip_addr->ai_family != port->raddr.addr.ss_family) { /* Wrong address family. */ - freeaddrinfo2(hints.ai_family, file_ip_addr); + freeaddrinfo_all(hints.ai_family, file_ip_addr); return; } /* Get the netmask */ if (cidr_slash) { - *cidr_slash = '/'; if (SockAddr_cidr_mask(&mask, cidr_slash + 1, - file_ip_addr->ai_family) < 0) + file_ip_addr->ai_family) < 0) goto hba_syntax; } else @@ -683,13 +685,13 @@ parse_hba(List *line, hbaPort *port, bool *found_p, bool *error_p) goto hba_syntax; token = lfirst(line); - ret = getaddrinfo2(token, NULL, &hints, &file_ip_mask); + ret = getaddrinfo_all(token, NULL, &hints, &file_ip_mask); if (ret || !file_ip_mask) goto hba_syntax; mask = (struct sockaddr_storage *)file_ip_mask->ai_addr; - if(file_ip_addr->ai_family != mask->ss_family) + if (file_ip_addr->ai_family != mask->ss_family) goto hba_syntax; } @@ -703,12 +705,13 @@ parse_hba(List *line, hbaPort *port, bool *found_p, bool *error_p) /* Must meet network restrictions */ if (!rangeSockAddr(&port->raddr.addr, - (struct sockaddr_storage *)file_ip_addr->ai_addr, mask)) + (struct sockaddr_storage *)file_ip_addr->ai_addr, + mask)) goto hba_freeaddr; - freeaddrinfo2(hints.ai_family, file_ip_addr); + freeaddrinfo_all(hints.ai_family, file_ip_addr); if (file_ip_mask) - freeaddrinfo2(hints.ai_family, file_ip_mask); + freeaddrinfo_all(hints.ai_family, file_ip_mask); } else goto hba_syntax; @@ -731,16 +734,16 @@ hba_syntax: else ereport(LOG, (errcode(ERRCODE_CONFIG_FILE_ERROR), - errmsg("missing entry in pg_hba.conf file at end of line %d", + errmsg("missing field in pg_hba.conf file at end of line %d", line_number))); *error_p = true; hba_freeaddr: if (file_ip_addr) - freeaddrinfo2(hints.ai_family, file_ip_addr); + freeaddrinfo_all(hints.ai_family, file_ip_addr); if (file_ip_mask) - freeaddrinfo2(hints.ai_family, file_ip_mask); + freeaddrinfo_all(hints.ai_family, file_ip_mask); } @@ -1209,14 +1212,14 @@ ident_inet(const SockAddr remote_addr, * Might look a little weird to first convert it to text and * then back to sockaddr, but it's protocol independent. */ - getnameinfo((struct sockaddr *)&remote_addr.addr, remote_addr.salen, - remote_addr_s, sizeof(remote_addr_s), - remote_port, sizeof(remote_port), - NI_NUMERICHOST | NI_NUMERICSERV); - getnameinfo((struct sockaddr *)&local_addr.addr, local_addr.salen, - local_addr_s, sizeof(local_addr_s), - local_port, sizeof(local_port), - NI_NUMERICHOST | NI_NUMERICSERV); + getnameinfo_all(&remote_addr.addr, remote_addr.salen, + remote_addr_s, sizeof(remote_addr_s), + remote_port, sizeof(remote_port), + NI_NUMERICHOST | NI_NUMERICSERV); + getnameinfo_all(&local_addr.addr, local_addr.salen, + local_addr_s, sizeof(local_addr_s), + local_port, sizeof(local_port), + NI_NUMERICHOST | NI_NUMERICSERV); snprintf(ident_port, sizeof(ident_port), "%d", IDENT_PORT); hints.ai_flags = AI_NUMERICHOST; @@ -1227,7 +1230,7 @@ ident_inet(const SockAddr remote_addr, hints.ai_canonname = NULL; hints.ai_addr = NULL; hints.ai_next = NULL; - rc = getaddrinfo2(remote_addr_s, ident_port, &hints, &ident_serv); + rc = getaddrinfo_all(remote_addr_s, ident_port, &hints, &ident_serv); if (rc || !ident_serv) return false; /* we don't expect this to happen */ @@ -1239,7 +1242,7 @@ ident_inet(const SockAddr remote_addr, hints.ai_canonname = NULL; hints.ai_addr = NULL; hints.ai_next = NULL; - rc = getaddrinfo2(local_addr_s, NULL, &hints, &la); + rc = getaddrinfo_all(local_addr_s, NULL, &hints, &la); if (rc || !la) return false; /* we don't expect this to happen */ @@ -1323,8 +1326,8 @@ ident_inet(const SockAddr remote_addr, ident_inet_done: if (sock_fd >= 0) closesocket(sock_fd); - freeaddrinfo2(remote_addr.addr.ss_family, ident_serv); - freeaddrinfo2(local_addr.addr.ss_family, la); + freeaddrinfo_all(remote_addr.addr.ss_family, ident_serv); + freeaddrinfo_all(local_addr.addr.ss_family, la); return ident_return; } diff --git a/src/backend/libpq/ip.c b/src/backend/libpq/ip.c index 091b381ec17..c5a0a485ef5 100644 --- a/src/backend/libpq/ip.c +++ b/src/backend/libpq/ip.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/libpq/ip.c,v 1.15 2003/06/12 08:15:28 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/libpq/ip.c,v 1.16 2003/07/23 23:30:40 tgl Exp $ * * This file and the IPV6 implementation were initially provided by * Nigel Kukard , Linux Based Systems Design @@ -53,15 +53,20 @@ static int rangeSockAddrAF_INET6(const struct sockaddr_in6 *addr, static int getaddrinfo_unix(const char *path, const struct addrinfo *hintsp, struct addrinfo **result); + +static int getnameinfo_unix(const struct sockaddr_un *sa, int salen, + char *node, int nodelen, + char *service, int servicelen, + int flags); #endif /* - * getaddrinfo2 - get address info for Unix, IPv4 and IPv6 sockets + * getaddrinfo_all - get address info for Unix, IPv4 and IPv6 sockets */ int -getaddrinfo2(const char *hostname, const char *servname, - const struct addrinfo *hintp, struct addrinfo **result) +getaddrinfo_all(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) @@ -75,7 +80,7 @@ getaddrinfo2(const char *hostname, const char *servname, /* - * freeaddrinfo2 - free addrinfo structures for IPv4, IPv6, or Unix + * freeaddrinfo_all - free addrinfo structures for IPv4, IPv6, or Unix * * Note: the ai_family field of the original hint structure must be passed * so that we can tell whether the addrinfo struct was built by the system's @@ -84,12 +89,12 @@ getaddrinfo2(const char *hostname, const char *servname, * not safe to look at ai_family in the addrinfo itself. */ void -freeaddrinfo2(int hint_ai_family, struct addrinfo *ai) +freeaddrinfo_all(int hint_ai_family, struct addrinfo *ai) { #ifdef HAVE_UNIX_SOCKETS if (hint_ai_family == AF_UNIX) { - /* struct was built by getaddrinfo_unix (see getaddrinfo2) */ + /* struct was built by getaddrinfo_unix (see getaddrinfo_all) */ while (ai != NULL) { struct addrinfo *p = ai; @@ -109,11 +114,53 @@ freeaddrinfo2(int hint_ai_family, struct addrinfo *ai) } +/* + * getnameinfo_all - get name info for Unix, IPv4 and IPv6 sockets + * + * The API of this routine differs from the standard getnameinfo() definition + * in two ways: first, the addr parameter is declared as sockaddr_storage + * rather than struct sockaddr, and second, the node and service fields are + * guaranteed to be filled with something even on failure return. + */ +int +getnameinfo_all(const struct sockaddr_storage *addr, int salen, + char *node, int nodelen, + char *service, int servicelen, + int flags) +{ + int rc; + +#ifdef HAVE_UNIX_SOCKETS + if (addr && addr->ss_family == AF_UNIX) + rc = getnameinfo_unix((const struct sockaddr_un *) addr, salen, + node, nodelen, + service, servicelen, + flags); + else +#endif + rc = getnameinfo((const struct sockaddr *) addr, salen, + node, nodelen, + service, servicelen, + flags); + + if (rc != 0) + { + if (node) + StrNCpy(node, "???", nodelen); + if (service) + StrNCpy(service, "???", servicelen); + } + + return rc; +} + + #if defined(HAVE_UNIX_SOCKETS) + /* ------- * getaddrinfo_unix - get unix socket info using IPv6-compatible API * - * Bug: only one addrinfo is set even though hintsp is NULL or + * Bugs: only one addrinfo is set even though hintsp is NULL or * ai_socktype is 0 * AI_CANONNAME is not supported. * ------- @@ -176,12 +223,59 @@ getaddrinfo_unix(const char *path, const struct addrinfo *hintsp, strcpy(unp->sun_path, path); -#if SALEN +#ifdef HAVE_STRUCT_SOCKADDR_STORAGE_SS_LEN unp->sun_len = sizeof(struct sockaddr_un); -#endif /* SALEN */ +#endif return 0; } + +/* + * Convert an address to a hostname. + */ +static int +getnameinfo_unix(const struct sockaddr_un *sa, int salen, + char *node, int nodelen, + char *service, int servicelen, + int flags) +{ + int ret = -1; + + /* Invalid arguments. */ + if (sa == NULL || sa->sun_family != AF_UNIX || + (node == NULL && service == NULL)) + { + return EAI_FAIL; + } + + /* We don't support those. */ + if ((node && !(flags & NI_NUMERICHOST)) + || (service && !(flags & NI_NUMERICSERV))) + { + return EAI_FAIL; + } + + if (node) + { + ret = snprintf(node, nodelen, "%s", "localhost"); + if (ret == -1 || ret > nodelen) + { + return EAI_MEMORY; + } + } + + if (service) + { + ret = snprintf(service, servicelen, "%s", sa->sun_path); + if (ret == -1 || ret > servicelen) + { + return EAI_MEMORY; + } + } + + return 0; +} + #endif /* HAVE_UNIX_SOCKETS */ diff --git a/src/backend/libpq/pqcomm.c b/src/backend/libpq/pqcomm.c index 7f3013925ae..7cd9e23f32c 100644 --- a/src/backend/libpq/pqcomm.c +++ b/src/backend/libpq/pqcomm.c @@ -30,7 +30,7 @@ * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Header: /cvsroot/pgsql/src/backend/libpq/pqcomm.c,v 1.158 2003/07/22 19:00:10 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/libpq/pqcomm.c,v 1.159 2003/07/23 23:30:40 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -190,16 +190,18 @@ StreamDoUnlink(void) #endif /* HAVE_UNIX_SOCKETS */ /* - * StreamServerPort -- open a sock stream "listening" port. + * StreamServerPort -- open a "listening" port to accept connections. * - * This initializes the Postmaster's connection-accepting port *fdP. + * Successfully opened sockets are added to the ListenSocket[] array, + * at the first position that isn't -1. * * RETURNS: STATUS_OK or STATUS_ERROR */ int StreamServerPort(int family, char *hostName, unsigned short portNumber, - char *unixSocketName, int ListenSocket[], int MaxListen) + char *unixSocketName, + int ListenSocket[], int MaxListen) { int fd, err; @@ -216,7 +218,7 @@ StreamServerPort(int family, char *hostName, unsigned short portNumber, /* Initialize hint structure */ MemSet(&hint, 0, sizeof(hint)); hint.ai_family = family; - hint.ai_flags = AI_PASSIVE | AI_ADDRCONFIG; + hint.ai_flags = AI_PASSIVE; hint.ai_socktype = SOCK_STREAM; #ifdef HAVE_UNIX_SOCKETS @@ -234,13 +236,18 @@ StreamServerPort(int family, char *hostName, unsigned short portNumber, service = portNumberStr; } - ret = getaddrinfo2(hostName, service, &hint, &addrs); - if (ret || addrs == NULL) + ret = getaddrinfo_all(hostName, service, &hint, &addrs); + if (ret || !addrs) { - ereport(LOG, - (errmsg("failed to translate hostname to address: %s", - gai_strerror(ret)))); - freeaddrinfo2(hint.ai_family, addrs); + if (hostName) + ereport(LOG, + (errmsg("could not translate hostname \"%s\", service \"%s\" to address: %s", + hostName, service, gai_strerror(ret)))); + else + ereport(LOG, + (errmsg("could not translate service \"%s\" to address: %s", + service, gai_strerror(ret)))); + freeaddrinfo_all(hint.ai_family, addrs); return STATUS_ERROR; } @@ -250,7 +257,8 @@ StreamServerPort(int family, char *hostName, unsigned short portNumber, { /* Only set up a unix domain socket when * they really asked for it. The service/port - * is different in that case. */ + * is different in that case. + */ continue; } @@ -258,17 +266,15 @@ StreamServerPort(int family, char *hostName, unsigned short portNumber, for (; listen_index < MaxListen; listen_index++) { if (ListenSocket[listen_index] == -1) - { break; - } } - if (listen_index == MaxListen) + if (listen_index >= MaxListen) { /* Nothing found. */ break; } - if ((fd = socket(addr->ai_family, addr->ai_socktype, - addr->ai_protocol)) < 0) + + if ((fd = socket(addr->ai_family, SOCK_STREAM, 0)) < 0) { ereport(LOG, (errcode_for_socket_access(), @@ -276,8 +282,6 @@ StreamServerPort(int family, char *hostName, unsigned short portNumber, continue; } - - if (!IS_AF_UNIX(addr->ai_family)) { if ((setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, @@ -363,12 +367,11 @@ StreamServerPort(int family, char *hostName, unsigned short portNumber, added++; } - freeaddrinfo(addrs); + freeaddrinfo_all(hint.ai_family, addrs); if (!added) - { return STATUS_ERROR; - } + return STATUS_OK; } diff --git a/src/backend/postmaster/pgstat.c b/src/backend/postmaster/pgstat.c index 5ed1247e951..f8882737eee 100644 --- a/src/backend/postmaster/pgstat.c +++ b/src/backend/postmaster/pgstat.c @@ -13,7 +13,7 @@ * * Copyright (c) 2001-2003, PostgreSQL Global Development Group * - * $Header: /cvsroot/pgsql/src/backend/postmaster/pgstat.c,v 1.39 2003/07/22 19:13:19 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/postmaster/pgstat.c,v 1.40 2003/07/23 23:30:40 tgl Exp $ * ---------- */ #include "postgres.h" @@ -147,7 +147,7 @@ void pgstat_init(void) { ACCEPT_TYPE_ARG3 alen; - struct addrinfo *addr = NULL, hints; + struct addrinfo *addrs = NULL, *addr, hints; int ret; /* @@ -189,17 +189,27 @@ pgstat_init(void) hints.ai_addr = NULL; hints.ai_canonname = NULL; hints.ai_next = NULL; - ret = getaddrinfo2("localhost", NULL, &hints, &addr); - if (ret || !addr) + ret = getaddrinfo_all("localhost", NULL, &hints, &addrs); + if (ret || !addrs) { ereport(LOG, - (errmsg("getaddrinfo2(\"localhost\") failed: %s", + (errmsg("could not resolve \"localhost\": %s", gai_strerror(ret)))); goto startup_failed; } - if ((pgStatSock = socket(addr->ai_family, - addr->ai_socktype, addr->ai_protocol)) < 0) + for (addr = addrs; addr; addr = addr->ai_next) + { +#ifdef HAVE_UNIX_SOCKETS + /* Ignore AF_UNIX sockets, if any are returned. */ + if (addr->ai_family == AF_UNIX) + continue; +#endif + if ((pgStatSock = socket(addr->ai_family, SOCK_DGRAM, 0)) >= 0) + break; + } + + if (!addr || pgStatSock < 0) { ereport(LOG, (errcode_for_socket_access(), @@ -218,8 +228,9 @@ pgstat_init(void) errmsg("could not bind socket for statistics: %m"))); goto startup_failed; } - freeaddrinfo2(hints.ai_family, addr); - addr = NULL; + + freeaddrinfo_all(hints.ai_family, addrs); + addrs = NULL; alen = sizeof(pgStatAddr); if (getsockname(pgStatSock, (struct sockaddr *)&pgStatAddr, &alen) < 0) @@ -272,8 +283,8 @@ pgstat_init(void) return; startup_failed: - if (addr) - freeaddrinfo2(hints.ai_family, addr); + if (addrs) + freeaddrinfo_all(hints.ai_family, addrs); if (pgStatSock >= 0) closesocket(pgStatSock); diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c index 614c76e64ee..fb64781bf8c 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.335 2003/07/22 20:29:13 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.336 2003/07/23 23:30:40 tgl Exp $ * * NOTES * @@ -168,9 +168,9 @@ int ReservedBackends; static char *progname = (char *) NULL; -/* The sockets we're listening to. */ +/* The socket(s) we're listening to. */ #define MAXLISTEN 10 -int ListenSocket[MAXLISTEN]; +static int ListenSocket[MAXLISTEN]; /* Used to reduce macros tests */ #ifdef EXEC_BACKEND @@ -277,7 +277,7 @@ static int ServerLoop(void); static int BackendStartup(Port *port); static int ProcessStartupPacket(Port *port, bool SSLdone); static void processCancelRequest(Port *port, void *pkt); -static int initMasks(fd_set *rmask, fd_set *wmask); +static int initMasks(fd_set *rmask); static void report_fork_failure_to_client(Port *port, int errnum); enum CAC_state { @@ -727,73 +727,80 @@ PostmasterMain(int argc, char *argv[]) * Establish input sockets. */ for (i = 0; i < MAXLISTEN; i++) - { ListenSocket[i] = -1; - } + if (NetServer) { if (VirtualHost && VirtualHost[0]) { - char *p, *q; + char *curhost, *endptr; char c = 0; - q = VirtualHost; - do + curhost = VirtualHost; + for (;;) { - p = strchr(q, ' '); - if (p) + while (*curhost == ' ') /* skip any extra spaces */ + curhost++; + if (*curhost == '\0') + break; + endptr = strchr(curhost, ' '); + if (endptr) { - c = *p; - *p = '\0'; + c = *endptr; + *endptr = '\0'; } - status = StreamServerPort(AF_UNSPEC, q, - (unsigned short) PostPortNumber, - UnixSocketDir, ListenSocket, MAXLISTEN); + status = StreamServerPort(AF_UNSPEC, curhost, + (unsigned short) PostPortNumber, + UnixSocketDir, + ListenSocket, MAXLISTEN); if (status != STATUS_OK) { - postmaster_error("cannot create tcpip " - "listen socket for: %s", p); + postmaster_error("could not create listen socket for \"%s\"", + curhost); } - if (p) + if (endptr) { - *p = c; - q = p + 1; + *endptr = c; + curhost = endptr + 1; } + else + break; } - while (p); } else { status = StreamServerPort(AF_UNSPEC, NULL, - (unsigned short) PostPortNumber, - UnixSocketDir, ListenSocket, MAXLISTEN); + (unsigned short) PostPortNumber, + UnixSocketDir, + ListenSocket, MAXLISTEN); if (status != STATUS_OK) { - postmaster_error("cannot create tcpip listen " - "socket."); + postmaster_error("could not create TCP/IP listen socket"); } } + #ifdef USE_RENDEZVOUS - if (rendezvous_name != NULL) - { - DNSServiceRegistrationCreate(rendezvous_name, - "_postgresql._tcp.", - "", - htonl(PostPortNumber), - "", - (DNSServiceRegistrationReply)reg_reply, - NULL); - } + if (rendezvous_name != NULL) + { + DNSServiceRegistrationCreate(rendezvous_name, + "_postgresql._tcp.", + "", + htonl(PostPortNumber), + "", + (DNSServiceRegistrationReply)reg_reply, + NULL); + } #endif } #ifdef HAVE_UNIX_SOCKETS status = StreamServerPort(AF_UNIX, NULL, - (unsigned short) PostPortNumber, - UnixSocketDir, ListenSocket, MAXLISTEN); + (unsigned short) PostPortNumber, + UnixSocketDir, + ListenSocket, MAXLISTEN); if (status != STATUS_OK) { - postmaster_error("cannot create UNIX stream port"); + postmaster_error("could not create UNIX stream port"); ExitPostmaster(1); } #endif @@ -994,7 +1001,7 @@ usage(const char *progname) static int ServerLoop(void) { - fd_set readmask, writemask; + fd_set readmask; int nSockets; struct timeval now, later; struct timezone tz; @@ -1002,13 +1009,12 @@ ServerLoop(void) gettimeofday(&now, &tz); - nSockets = initMasks(&readmask, &writemask); + nSockets = initMasks(&readmask); for (;;) { Port *port; - fd_set rmask, - wmask; + fd_set rmask; struct timeval timeout; /* @@ -1057,11 +1063,11 @@ ServerLoop(void) * Wait for something to happen. */ memcpy((char *) &rmask, (char *) &readmask, sizeof(fd_set)); - memcpy((char *) &wmask, (char *) &writemask, sizeof(fd_set)); PG_SETMASK(&UnBlockSig); - if (select(nSockets, &rmask, &wmask, (fd_set *) NULL, &timeout) < 0) + if (select(nSockets, &rmask, (fd_set *) NULL, + (fd_set *) NULL, &timeout) < 0) { PG_SETMASK(&BlockSig); if (errno == EINTR || errno == EWOULDBLOCK) @@ -1096,12 +1102,14 @@ ServerLoop(void) } /* - * New connection pending on our well-known port's socket? If so, + * New connection pending on any of our sockets? If so, * fork a child process to deal with it. */ for (i = 0; i < MAXLISTEN; i++) { - if (ListenSocket[i] != -1 && FD_ISSET(ListenSocket[i], &rmask)) + if (ListenSocket[i] == -1) + break; + if (FD_ISSET(ListenSocket[i], &rmask)) { port = ConnCreate(ListenSocket[i]); if (port) @@ -1126,28 +1134,27 @@ ServerLoop(void) /* - * Initialise the read and write masks for select() for the well-known ports + * Initialise the masks for select() for the ports * we are listening on. Return the number of sockets to listen on. */ static int -initMasks(fd_set *rmask, fd_set *wmask) +initMasks(fd_set *rmask) { int nsocks = -1; int i; FD_ZERO(rmask); - FD_ZERO(wmask); for (i = 0; i < MAXLISTEN; i++) { int fd = ListenSocket[i]; - if (fd != -1) - { - FD_SET(fd, rmask); - if (fd > nsocks) - nsocks = fd; - } + + if (fd == -1) + break; + FD_SET(fd, rmask); + if (fd > nsocks) + nsocks = fd; } return nsocks + 1; @@ -2352,17 +2359,15 @@ BackendFork(Port *port) */ remote_host[0] = '\0'; remote_port[0] = '\0'; - if (!getnameinfo((struct sockaddr *)&port->raddr.addr, - port->raddr.salen, - remote_host, sizeof(remote_host), - remote_port, sizeof(remote_host), - (log_hostname ? 0 : NI_NUMERICHOST) | NI_NUMERICSERV)) + if (getnameinfo_all(&port->raddr.addr, port->raddr.salen, + remote_host, sizeof(remote_host), + remote_port, sizeof(remote_port), + (log_hostname ? 0 : NI_NUMERICHOST) | NI_NUMERICSERV)) { - getnameinfo((struct sockaddr *)&port->raddr.addr, - port->raddr.salen, - remote_host, sizeof(remote_host), - remote_port, sizeof(remote_host), - NI_NUMERICHOST | NI_NUMERICSERV); + getnameinfo_all(&port->raddr.addr, port->raddr.salen, + remote_host, sizeof(remote_host), + remote_port, sizeof(remote_port), + NI_NUMERICHOST | NI_NUMERICSERV); } if (Log_connections) @@ -2373,7 +2378,7 @@ BackendFork(Port *port) if (LogSourcePort) { /* modify remote_host for use in ps status */ - char tmphost[sizeof(remote_host) + 10]; + char tmphost[NI_MAXHOST]; snprintf(tmphost, sizeof(tmphost), "%s:%s", remote_host, remote_port); StrNCpy(remote_host, tmphost, sizeof(remote_host)); diff --git a/src/include/getaddrinfo.h b/src/include/getaddrinfo.h index ced6df07e9a..6312482a7a9 100644 --- a/src/include/getaddrinfo.h +++ b/src/include/getaddrinfo.h @@ -3,7 +3,6 @@ * getaddrinfo.h * Support getaddrinfo() on platforms that don't have it. * - * * Note: we use our own routines on platforms that don't HAVE_STRUCT_ADDRINFO, * whether or not the library routine getaddrinfo() can be found. This * policy is needed because on some platforms a manually installed libbind.a @@ -16,7 +15,7 @@ * * Copyright (c) 2003, PostgreSQL Global Development Group * - * $Id: getaddrinfo.h,v 1.6 2003/06/12 08:15:29 momjian Exp $ + * $Id: getaddrinfo.h,v 1.7 2003/07/23 23:30:40 tgl Exp $ * *------------------------------------------------------------------------- */ diff --git a/src/include/libpq/ip.h b/src/include/libpq/ip.h index b770d33bfe3..5c614b16815 100644 --- a/src/include/libpq/ip.h +++ b/src/include/libpq/ip.h @@ -5,7 +5,7 @@ * * Copyright (c) 2003, PostgreSQL Global Development Group * - * $Id: ip.h,v 1.8 2003/06/12 07:36:51 momjian Exp $ + * $Id: ip.h,v 1.9 2003/07/23 23:30:41 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -16,10 +16,15 @@ #include "libpq/pqcomm.h" -extern int getaddrinfo2(const char *hostname, const char *servname, - const struct addrinfo *hintp, - struct addrinfo **result); -extern void freeaddrinfo2(int hint_ai_family, struct addrinfo *ai); +extern int getaddrinfo_all(const char *hostname, const char *servname, + const struct addrinfo *hintp, + struct addrinfo **result); +extern void freeaddrinfo_all(int hint_ai_family, struct addrinfo *ai); + +extern int getnameinfo_all(const struct sockaddr_storage *addr, int salen, + char *node, int nodelen, + char *service, int servicelen, + int flags); extern int rangeSockAddr(const struct sockaddr_storage *addr, const struct sockaddr_storage *netaddr, @@ -29,7 +34,7 @@ extern int SockAddr_cidr_mask(struct sockaddr_storage **mask, char *numbits, int family); #ifdef HAVE_UNIX_SOCKETS -#define IS_AF_UNIX(fam) (fam == AF_UNIX) +#define IS_AF_UNIX(fam) ((fam) == AF_UNIX) #else #define IS_AF_UNIX(fam) (0) #endif diff --git a/src/include/libpq/pqcomm.h b/src/include/libpq/pqcomm.h index 0cabdc24c11..caa186b8320 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.89 2003/07/15 17:54:34 tgl Exp $ + * $Id: pqcomm.h,v 1.90 2003/07/23 23:30:41 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -32,38 +32,9 @@ #include #endif /* not WIN32 */ -#ifndef HAVE_STRUCT_SOCKADDR_STORAGE -/* Define a struct sockaddr_storage if we don't have one. */ +#ifdef HAVE_STRUCT_SOCKADDR_STORAGE -#define _SS_MAXSIZE 128 /* Implementation specific max size */ - -#ifdef __CYGWIN__ -typedef unsigned short sa_family_t; -#endif - -/* This must exactly match the non-padding fields of sockaddr_storage! */ -struct nopad_sockaddr_storage { -#ifdef SALEN - uint8 __ss_len; /* address length */ -#endif - sa_family_t ss_family; /* address family */ - - int64 __ss_align; /* ensures struct is properly aligned */ -}; - -struct sockaddr_storage { -#ifdef SALEN - uint8 __ss_len; /* address length */ -#endif - sa_family_t ss_family; /* address family */ - - int64 __ss_align; /* ensures struct is properly aligned */ - - char __ss_pad[_SS_MAXSIZE - sizeof(struct nopad_sockaddr_storage)]; - /* ensures struct has desired size */ -}; - -#elif !defined(HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY) +#ifndef HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY # ifdef HAVE_STRUCT_SOCKADDR_STORAGE___SS_FAMILY # define ss_family __ss_family # else @@ -71,17 +42,37 @@ struct sockaddr_storage { # endif #endif +#ifdef HAVE_STRUCT_SOCKADDR_STORAGE___SS_LEN +#define ss_len __ss_len +#define HAVE_STRUCT_SOCKADDR_STORAGE_SS_LEN 1 +#endif + +#else /* !HAVE_STRUCT_SOCKADDR_STORAGE */ + +/* Define a struct sockaddr_storage if we don't have one. */ + +struct sockaddr_storage { + union { + struct sockaddr sa; /* get the system-dependent fields */ + int64 ss_align; /* ensures struct is properly aligned */ + char ss_pad[128]; /* ensures struct has desired size */ + } ss_stuff; +}; + +#define ss_family ss_stuff.sa.sa_family +/* It should have an ss_len field if sockaddr has sa_len. */ +#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN +#define ss_len ss_stuff.sa.sa_len +#define HAVE_STRUCT_SOCKADDR_STORAGE_SS_LEN 1 +#endif + +#endif /* HAVE_STRUCT_SOCKADDR_STORAGE */ + typedef struct { struct sockaddr_storage addr; ACCEPT_TYPE_ARG3 salen; } SockAddr; -/* Some systems don't have it, so default it to 0 so it doesn't - * have any effect on those systems. */ -#ifndef AI_ADDRCONFIG -#define AI_ADDRCONFIG 0 -#endif - /* Configure the UNIX socket location for the well known port. */ #define UNIXSOCK_PATH(path,port,defpath) \ diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in index 41806fe8fb2..2fe4cd3ea12 100644 --- a/src/include/pg_config.h.in +++ b/src/include/pg_config.h.in @@ -420,15 +420,24 @@ /* Define to 1 if the system has the type `struct fcred'. */ #undef HAVE_STRUCT_FCRED +/* Define to 1 if `sa_len' is member of `struct sockaddr'. */ +#undef HAVE_STRUCT_SOCKADDR_SA_LEN + /* Define to 1 if the system has the type `struct sockaddr_storage'. */ #undef HAVE_STRUCT_SOCKADDR_STORAGE /* Define to 1 if `ss_family' is member of `struct sockaddr_storage'. */ #undef HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY +/* Define to 1 if `ss_len' is member of `struct sockaddr_storage'. */ +#undef HAVE_STRUCT_SOCKADDR_STORAGE_SS_LEN + /* Define to 1 if `__ss_family' is member of `struct sockaddr_storage'. */ #undef HAVE_STRUCT_SOCKADDR_STORAGE___SS_FAMILY +/* Define to 1 if `__ss_len' is member of `struct sockaddr_storage'. */ +#undef HAVE_STRUCT_SOCKADDR_STORAGE___SS_LEN + /* Define to 1 if the system has the type `struct sockaddr_un'. */ #undef HAVE_STRUCT_SOCKADDR_UN @@ -594,7 +603,8 @@ /* Define to select SysV-style shared memory. */ #undef USE_SYSV_SHARED_MEMORY -/* Define to 1 to build libpq and ecpg to be thread-safe. (--with-threads) */ +/* Define to 1 to build libpq and ecpg to be thread-safe. + (--enable-thread-safeness) */ #undef USE_THREADS /* Define to select unnamed POSIX semaphores. */ diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c index a931fe9fa24..0518cd21b4c 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.252 2003/06/23 19:20:24 tgl Exp $ + * $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-connect.c,v 1.253 2003/07/23 23:30:41 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -759,26 +759,33 @@ connectNoDelay(PGconn *conn) static void connectFailureMessage(PGconn *conn, int errorno) { - char hostname[NI_MAXHOST]; - char service[NI_MAXHOST]; char sebuf[256]; - getnameinfo((struct sockaddr *)&conn->raddr.addr, conn->raddr.salen, - hostname, sizeof(hostname), service, sizeof(service), - NI_NUMERICHOST | NI_NUMERICSERV); - if (conn->raddr.addr.ss_family == AF_UNIX) +#ifdef HAVE_UNIX_SOCKETS + if (IS_AF_UNIX(conn->raddr.addr.ss_family)) + { + char service[NI_MAXHOST]; + + getnameinfo_all(&conn->raddr.addr, conn->raddr.salen, + NULL, 0, + service, sizeof(service), + NI_NUMERICSERV); printfPQExpBuffer(&conn->errorMessage, libpq_gettext( "could not connect to server: %s\n" "\tIs the server running locally and accepting\n" "\tconnections on Unix domain socket \"%s\"?\n" ), - SOCK_STRERROR(errorno, sebuf, sizeof(sebuf)), service); + SOCK_STRERROR(errorno, sebuf, sizeof(sebuf)), + service); + } else +#endif /* HAVE_UNIX_SOCKETS */ + { printfPQExpBuffer(&conn->errorMessage, libpq_gettext( "could not connect to server: %s\n" - "\tIs the server running on host %s and accepting\n" + "\tIs the server running on host \"%s\" and accepting\n" "\tTCP/IP connections on port %s?\n" ), SOCK_STRERROR(errorno, sebuf, sizeof(sebuf)), @@ -788,6 +795,7 @@ connectFailureMessage(PGconn *conn, int errorno) ? conn->pghost : "???"), conn->pgport); + } } @@ -802,7 +810,7 @@ static int connectDBStart(PGconn *conn) { int portnum; - char portstr[64]; + char portstr[128]; struct addrinfo *addrs = NULL; struct addrinfo hint; const char *node = NULL; @@ -816,7 +824,7 @@ connectDBStart(PGconn *conn) conn->outCount = 0; /* - * Determine the parameters to pass to getaddrinfo2. + * Determine the parameters to pass to getaddrinfo_all. */ /* Initialize hint structure */ @@ -854,14 +862,19 @@ connectDBStart(PGconn *conn) } #endif /* HAVE_UNIX_SOCKETS */ - /* Use getaddrinfo2() to resolve the address */ - ret = getaddrinfo2(node, portstr, &hint, &addrs); - if (ret || addrs == NULL) + /* Use getaddrinfo_all() to resolve the address */ + ret = getaddrinfo_all(node, portstr, &hint, &addrs); + if (ret || !addrs) { - printfPQExpBuffer(&conn->errorMessage, - libpq_gettext("getaddrinfo() failed: %s\n"), - gai_strerror(ret)); - freeaddrinfo2(hint.ai_family, addrs); + if (node) + printfPQExpBuffer(&conn->errorMessage, + libpq_gettext("could not translate hostname \"%s\" to address: %s\n"), + node, gai_strerror(ret)); + else + printfPQExpBuffer(&conn->errorMessage, + libpq_gettext("could not translate local service to address: %s\n"), + gai_strerror(ret)); + freeaddrinfo_all(hint.ai_family, addrs); goto connect_errReturn; } @@ -1068,7 +1081,7 @@ keep_going: /* We will come back to here until there { /* * Try to initiate a connection to one of the addresses - * returned by getaddrinfo2(). conn->addr_cur is the + * returned by getaddrinfo_all(). conn->addr_cur is the * next one to try. We fail when we run out of addresses * (reporting the error returned for the *last* alternative, * which may not be what users expect :-(). @@ -1083,9 +1096,7 @@ keep_going: /* We will come back to here until there conn->raddr.salen = addr_cur->ai_addrlen; /* Open a socket */ - conn->sock = socket(addr_cur->ai_family, - addr_cur->ai_socktype, - addr_cur->ai_protocol); + conn->sock = socket(addr_cur->ai_family, SOCK_STREAM, 0); if (conn->sock < 0) { /* @@ -1263,15 +1274,12 @@ retry_connect: * If SSL is enabled and we haven't already got it running, * request it instead of sending the startup message. */ - -#ifdef HAVE_UNIX_SOCKETS - if (conn->raddr.addr.ss_family == AF_UNIX) + if (IS_AF_UNIX(conn->raddr.addr.ss_family)) { /* Don't bother requesting SSL over a Unix socket */ conn->allow_ssl_try = false; conn->require_ssl = false; } -#endif if (conn->allow_ssl_try && conn->ssl == NULL) { ProtocolVersion pv; @@ -1712,7 +1720,7 @@ retry_ssl_read: } /* We can release the address list now. */ - freeaddrinfo2(conn->addrlist_family, conn->addrlist); + freeaddrinfo_all(conn->addrlist_family, conn->addrlist); conn->addrlist = NULL; conn->addr_cur = NULL; @@ -1886,7 +1894,7 @@ freePGconn(PGconn *conn) /* Note that conn->Pfdebug is not ours to close or free */ if (conn->notifyList) DLFreeList(conn->notifyList); - freeaddrinfo2(conn->addrlist_family, conn->addrlist); + freeaddrinfo_all(conn->addrlist_family, conn->addrlist); if (conn->lobjfuncs) free(conn->lobjfuncs); if (conn->inBuffer) diff --git a/src/port/getaddrinfo.c b/src/port/getaddrinfo.c index cc584a2209a..011437bb9b7 100644 --- a/src/port/getaddrinfo.c +++ b/src/port/getaddrinfo.c @@ -3,12 +3,16 @@ * getaddrinfo.c * Support getaddrinfo() on platforms that don't have it. * + * We also supply getnameinfo() here, assuming that the platform will have + * it if and only if it has getaddrinfo(). If this proves false on some + * platform, we'll need to split this file and provide a separate configure + * test for getnameinfo(). + * * * Copyright (c) 2003, PostgreSQL Global Development Group * - * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/port/getaddrinfo.c,v 1.9 2003/06/23 23:52:00 momjian Exp $ + * $Header: /cvsroot/pgsql/src/port/getaddrinfo.c,v 1.10 2003/07/23 23:30:41 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -22,9 +26,6 @@ #include #include #include -#ifdef HAVE_UNIX_SOCKETS -#include -#endif #endif #include "getaddrinfo.h" @@ -124,8 +125,9 @@ getaddrinfo(const char *node, const char *service, if (service) sin.sin_port = htons((unsigned short) atoi(service)); -#if SALEN - sin.sin_len = sizeof(sin); + +#ifdef HAVE_STRUCT_SOCKADDR_STORAGE_SS_LEN + sin.sin_len = sizeof(sin); #endif ai = malloc(sizeof(*ai)); @@ -209,7 +211,7 @@ gai_strerror(int errcode) } /* - * Convert an address to a hostname. + * Convert an ipv4 address to a hostname. * * Bugs: - Only supports NI_NUMERICHOST and NI_NUMERICSERV * It will never resolv a hostname. @@ -217,11 +219,9 @@ gai_strerror(int errcode) */ int getnameinfo(const struct sockaddr *sa, int salen, - char *node, int nodelen, - char *service, int servicelen, int flags) + char *node, int nodelen, + char *service, int servicelen, int flags) { - int ret = -1; - /* Invalid arguments. */ if (sa == NULL || (node == NULL && service == NULL)) { @@ -242,45 +242,36 @@ getnameinfo(const struct sockaddr *sa, int salen, } #endif - if (service) - { - if (sa->sa_family == AF_INET) - { - ret = snprintf(service, servicelen, "%d", - ntohs(((struct sockaddr_in *)sa)->sin_port)); - } -#ifdef HAVE_UNIX_SOCKETS - else if (sa->sa_family == AF_UNIX) - { - ret = snprintf(service, servicelen, "%s", - ((struct sockaddr_un *)sa)->sun_path); - } -#endif - if (ret == -1 || ret > servicelen) - { - return EAI_MEMORY; - } - } - if (node) { + int ret = -1; + if (sa->sa_family == AF_INET) { char *p; p = inet_ntoa(((struct sockaddr_in *)sa)->sin_addr); ret = snprintf(node, nodelen, "%s", p); } -#ifdef HAVE_UNIX_SOCKETS - else if (sa->sa_family == AF_UNIX) - { - ret = snprintf(node, nodelen, "%s", "localhost"); - } -#endif if (ret == -1 || ret > nodelen) { return EAI_MEMORY; } } + if (service) + { + int ret = -1; + + if (sa->sa_family == AF_INET) + { + ret = snprintf(service, servicelen, "%d", + ntohs(((struct sockaddr_in *)sa)->sin_port)); + } + if (ret == -1 || ret > servicelen) + { + return EAI_MEMORY; + } + } + return 0; }