]> granicus.if.org Git - postgresql/commitdiff
Have a go at fixing various outstanding portability issues in code that
authorTom Lane <tgl@sss.pgh.pa.us>
Wed, 23 Jul 2003 23:30:41 +0000 (23:30 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Wed, 23 Jul 2003 23:30:41 +0000 (23:30 +0000)
was modified for IPv6.  Use a robust definition of struct sockaddr_storage,
do a proper configure test to see if ss_len exists, don't assume that
getnameinfo() will handle AF_UNIX sockets, don't trust getaddrinfo to
return the protocol we ask for, etc.  This incorporates several outstanding
patches from Kurt Roeckx, but I'm to blame for anything that doesn't
work ...

15 files changed:
config/c-library.m4
configure
configure.in
src/backend/libpq/auth.c
src/backend/libpq/hba.c
src/backend/libpq/ip.c
src/backend/libpq/pqcomm.c
src/backend/postmaster/pgstat.c
src/backend/postmaster/postmaster.c
src/include/getaddrinfo.h
src/include/libpq/ip.h
src/include/libpq/pqcomm.h
src/include/pg_config.h.in
src/interfaces/libpq/fe-connect.c
src/port/getaddrinfo.c

index d301b0155cf428e56b025ed5416001136e0833f3..d6acd8c98b69cc0c3dcabe600e129716edf8bbb4 100644 (file)
@@ -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 <sys/types.h>
@@ -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 <sys/types.h>
 #ifdef HAVE_SYS_SOCKET_H
 #include <sys/socket.h>
 #endif
-])])# PGAC_STRUCT_SOCKADDR_STORAGE_SS_FAMILY
+])])# PGAC_STRUCT_SOCKADDR_STORAGE_MEMBERS
 
 
 # PGAC_STRUCT_ADDRINFO
index 99bce0c0410ae1f6c8f2768daa359ab7e0ac95a5..24066b6fac363cc9e79db6245beff6649f33a1bb 100755 (executable)
--- 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 <sys/types.h>
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#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 <sys/types.h>
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#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 <sys/types.h>
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#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
index 515d53c183a46ec9df9f64e3cc73979956fc9d73..d189a5ffdb39279f86fe6edd608d6164fca2d64e 100644 (file)
@@ -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], [], [],
index ca6bfcf4d7ee3ba10cb981605abab2598851590a..a24f0978466a126510b41053399fac4d62c58184 100644 (file)
@@ -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),
index f0bd0b8515497117c2a9140fb8a04d13d609f874..0d98e729a40eb4e60cacd03a6636ef8e8b2a79fe 100644 (file)
@@ -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;
 }
 
index 091b381ec179f9d9b5a63594519e59864d08ddfd..c5a0a485ef5c852b2a0d311aafedd89823127a6c 100644 (file)
@@ -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 <nkukard@lbsd.net>, 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 */
 
 
index 7f3013925aea91ce4e348fd1871526f5a3647c25..7cd9e23f32cc9752007b316b9fd4975728364788 100644 (file)
@@ -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;
 }
 
index 5ed1247e9519fe4f37a414cfa71e16e46782bcf5..f8882737eeed5f611f2ada4df0f39d183c32c1a2 100644 (file)
@@ -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);
index 614c76e64eeff63e7c7f4eca1a9c04f1a0dc91ed..fb64781bf8c09f0ba70506b70f973306875df076 100644 (file)
@@ -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))
-       {
-               getnameinfo((struct sockaddr *)&port->raddr.addr,
-                       port->raddr.salen,
-                       remote_host, sizeof(remote_host),
-                       remote_port, sizeof(remote_host),
-                       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_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));
index ced6df07e9a6e441b58ae753b9653d824316153c..6312482a7a9b1444d975eab756664b63a81222fd 100644 (file)
@@ -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 $
  *
  *-------------------------------------------------------------------------
  */
index b770d33bfe391274d0c74614811b12f5bd8f8228..5c614b168153aa82797d736440b27a1e989a5f6e 100644 (file)
@@ -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 $
  *
  *-------------------------------------------------------------------------
  */
 #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
index 0cabdc24c1177d3ae97369d605a67e8f99444d01..caa186b8320f015154ac837d413174358d19a7b7 100644 (file)
@@ -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 $
  *
  *-------------------------------------------------------------------------
  */
 #include <netinet/in.h>
 #endif   /* not WIN32 */
 
-#ifndef        HAVE_STRUCT_SOCKADDR_STORAGE
-/* Define a struct sockaddr_storage if we don't have one. */
-
-#define _SS_MAXSIZE    128             /* Implementation specific max size */
+#ifdef HAVE_STRUCT_SOCKADDR_STORAGE
 
-#ifdef __CYGWIN__
-typedef unsigned short sa_family_t;
+#ifndef HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY
+# ifdef HAVE_STRUCT_SOCKADDR_STORAGE___SS_FAMILY
+#  define ss_family __ss_family
+# else
+#  error struct sockaddr_storage does not provide an ss_family member
+# endif
 #endif
 
-/* This must exactly match the non-padding fields of sockaddr_storage! */
-struct nopad_sockaddr_storage {
-#ifdef SALEN
-    uint8      __ss_len;                       /* address length */
+#ifdef HAVE_STRUCT_SOCKADDR_STORAGE___SS_LEN
+#define ss_len __ss_len
+#define HAVE_STRUCT_SOCKADDR_STORAGE_SS_LEN 1
 #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 */
+#else /* !HAVE_STRUCT_SOCKADDR_STORAGE */
 
-    int64      __ss_align;                     /* ensures struct is properly aligned */
+/* Define a struct sockaddr_storage if we don't have one. */
 
-    char       __ss_pad[_SS_MAXSIZE - sizeof(struct nopad_sockaddr_storage)];
-                                                               /* ensures struct has desired size */
+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;
 };
 
-#elif !defined(HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY)
-# ifdef HAVE_STRUCT_SOCKADDR_STORAGE___SS_FAMILY
-#  define ss_family __ss_family
-# else
-#  error struct sockaddr_storage does not provide an ss_family member
-# endif
+#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) \
index 41806fe8fb2a7bc8ca57ab854b5ba44dc8f85533..2fe4cd3ea1280c47b0a5f8feb1799a0f9b6d8e7f 100644 (file)
 /* 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
 
 /* 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. */
index a931fe9fa24bd14c266a4dde44f0122da9e89920..0518cd21b4c75c070731a54e766f0ce72fb7afeb 100644 (file)
@@ -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)
index cc584a2209a85077a217941126929cfdaecb5242..011437bb9b7bd2dcf52d4115894b275feddd76f1 100644 (file)
@@ -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
  *
+ * 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 <netdb.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
-#ifdef HAVE_UNIX_SOCKETS
-#include <sys/un.h>
-#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,41 +242,32 @@ getnameinfo(const struct sockaddr *sa, int salen,
        }
 #endif
 
-       if (service)
+       if (node)
        {
+               int             ret = -1;
+
                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);
+                       char    *p;
+                       p = inet_ntoa(((struct sockaddr_in *)sa)->sin_addr);
+                       ret = snprintf(node, nodelen, "%s", p);
                }
-#endif
-               if (ret == -1 || ret > servicelen)
+               if (ret == -1 || ret > nodelen)
                {
                        return EAI_MEMORY;
                }
        }
 
-       if (node)
+       if (service)
        {
+               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");
+                       ret = snprintf(service, servicelen, "%d",
+                                                  ntohs(((struct sockaddr_in *)sa)->sin_port));
                }
-#endif
-               if (ret == -1 || ret > nodelen)
+               if (ret == -1 || ret > servicelen)
                {
                        return EAI_MEMORY;
                }