function if the OS doesn't provide one.
-# This exports HAVE_IPV6 to both C files and Makefiles
-echo "$as_me:$LINENO: checking for getaddrinfo" >&5
-echo $ECHO_N "checking for getaddrinfo... $ECHO_C" >&6
-if test "${ac_cv_func_getaddrinfo+set}" = set; then
+echo "$as_me:$LINENO: checking for struct sockaddr_in6" >&5
+echo $ECHO_N "checking for struct sockaddr_in6... $ECHO_C" >&6
+if test "${ac_cv_type_struct_sockaddr_in6+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
#include "confdefs.h"
-/* System header to define __stub macros and hopefully few prototypes,
- which can conflict with char getaddrinfo (); below. */
-#include <assert.h>
-/* Override any gcc2 internal prototype to avoid an error. */
-#ifdef __cplusplus
-extern "C"
-#endif
-/* We use char because int might match the return type of a gcc2
- builtin and then its argument prototype would still apply. */
-char getaddrinfo ();
-char (*f) ();
+$ac_includes_default
+#include <netinet/in.h>
#ifdef F77_DUMMY_MAIN
# ifdef __cplusplus
int
main ()
{
-/* The GNU C library defines this for functions which it implements
- to always fail with ENOSYS. Some functions are actually named
- something starting with __ and the normal name is an alias. */
-#if defined (__stub_getaddrinfo) || defined (__stub___getaddrinfo)
-choke me
-#else
-f = getaddrinfo;
-#endif
-
+if ((struct sockaddr_in6 *) 0)
+ return 0;
+if (sizeof (struct sockaddr_in6))
+ return 0;
;
return 0;
}
_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>&5
+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_exeext'
+ { 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_func_getaddrinfo=yes
+ ac_cv_type_struct_sockaddr_in6=yes
else
echo "$as_me: failed program was:" >&5
cat conftest.$ac_ext >&5
-ac_cv_func_getaddrinfo=no
+ac_cv_type_struct_sockaddr_in6=no
fi
-rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+rm -f conftest.$ac_objext conftest.$ac_ext
fi
-echo "$as_me:$LINENO: result: $ac_cv_func_getaddrinfo" >&5
-echo "${ECHO_T}$ac_cv_func_getaddrinfo" >&6
-if test $ac_cv_func_getaddrinfo = yes; then
- echo "$as_me:$LINENO: checking for struct sockaddr_in6" >&5
-echo $ECHO_N "checking for struct sockaddr_in6... $ECHO_C" >&6
-if test "${ac_cv_type_struct_sockaddr_in6+set}" = set; then
+echo "$as_me:$LINENO: result: $ac_cv_type_struct_sockaddr_in6" >&5
+echo "${ECHO_T}$ac_cv_type_struct_sockaddr_in6" >&6
+if test $ac_cv_type_struct_sockaddr_in6 = yes; then
+ echo "$as_me:$LINENO: checking for inet_ntop" >&5
+echo $ECHO_N "checking for inet_ntop... $ECHO_C" >&6
+if test "${ac_cv_func_inet_ntop+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
#include "confdefs.h"
-$ac_includes_default
-#include <netinet/in.h>
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char inet_ntop (); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char inet_ntop ();
+char (*f) ();
#ifdef F77_DUMMY_MAIN
# ifdef __cplusplus
int
main ()
{
-if ((struct sockaddr_in6 *) 0)
- return 0;
-if (sizeof (struct sockaddr_in6))
- return 0;
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_inet_ntop) || defined (__stub___inet_ntop)
+choke me
+#else
+f = inet_ntop;
+#endif
+
;
return 0;
}
_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>&5
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -s conftest.$ac_objext'
+ { ac_try='test -s conftest$ac_exeext'
{ (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_type_struct_sockaddr_in6=yes
+ ac_cv_func_inet_ntop=yes
else
echo "$as_me: failed program was:" >&5
cat conftest.$ac_ext >&5
-ac_cv_type_struct_sockaddr_in6=no
+ac_cv_func_inet_ntop=no
fi
-rm -f conftest.$ac_objext conftest.$ac_ext
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
fi
-echo "$as_me:$LINENO: result: $ac_cv_type_struct_sockaddr_in6" >&5
-echo "${ECHO_T}$ac_cv_type_struct_sockaddr_in6" >&6
-if test $ac_cv_type_struct_sockaddr_in6 = yes; then
- HAVE_IPV6="yes"; cat >>confdefs.h <<\_ACEOF
+echo "$as_me:$LINENO: result: $ac_cv_func_inet_ntop" >&5
+echo "${ECHO_T}$ac_cv_func_inet_ntop" >&6
+if test $ac_cv_func_inet_ntop = yes; then
+ cat >>confdefs.h <<\_ACEOF
#define HAVE_IPV6 1
_ACEOF
fi
-
echo "$as_me:$LINENO: checking for PS_STRINGS" >&5
echo $ECHO_N "checking for PS_STRINGS... $ECHO_C" >&6
if test "${pgac_cv_var_PS_STRINGS+set}" = set; then
-for ac_func in fseeko gethostname getopt_long getrusage inet_aton random srandom strcasecmp strdup strerror strtol strtoul
+
+for ac_func in fseeko getaddrinfo gethostname getopt_long getrusage inet_aton random srandom strcasecmp strdup strerror strtol strtoul
do
as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
echo "$as_me:$LINENO: checking for $ac_func" >&5
s,@python_includespec@,$python_includespec,;t t
s,@python_libspec@,$python_libspec,;t t
s,@LIBOBJS@,$LIBOBJS,;t t
-s,@HAVE_IPV6@,$HAVE_IPV6,;t t
s,@HPUXMATHLIB@,$HPUXMATHLIB,;t t
s,@HAVE_POSIX_SIGNALS@,$HAVE_POSIX_SIGNALS,;t t
s,@MSGFMT@,$MSGFMT,;t t
dnl Process this file with autoconf to produce a configure script.
-dnl $Header: /cvsroot/pgsql/configure.in,v 1.239 2003/03/21 17:18:34 petere Exp $
+dnl $Header: /cvsroot/pgsql/configure.in,v 1.240 2003/03/29 11:31:51 petere Exp $
dnl
dnl Developers, please strive to achieve this order:
dnl
AC_CHECK_DECLS(fdatasync, [], [], [#include <unistd.h>])
-# This exports HAVE_IPV6 to both C files and Makefiles
-AC_CHECK_FUNC(getaddrinfo,
- [AC_CHECK_TYPE(struct sockaddr_in6,
- [HAVE_IPV6="yes"; AC_DEFINE(HAVE_IPV6, 1)],
- [],
+AC_CHECK_TYPE([struct sockaddr_in6],
+ [AC_CHECK_FUNC(inet_ntop,
+ [AC_DEFINE(HAVE_IPV6, 1)])],
+ [],
[$ac_includes_default
-#include <netinet/in.h>])])
-AC_SUBST(HAVE_IPV6)
+#include <netinet/in.h>])
AC_CACHE_CHECK([for PS_STRINGS], [pgac_cv_var_PS_STRINGS],
[AC_TRY_LINK(
AC_CHECK_FUNCS([fpclass fp_class fp_class_d class], [break])
fi
-AC_REPLACE_FUNCS([fseeko gethostname getopt_long getrusage inet_aton random srandom strcasecmp strdup strerror strtol strtoul])
+AC_REPLACE_FUNCS([fseeko getaddrinfo gethostname getopt_long getrusage inet_aton random srandom strcasecmp strdup strerror strtol strtoul])
# BSD/OS & NetBSD use a custom fseeko/ftello built on fsetpos/fgetpos
# We override the previous test that said fseeko/ftello didn't exist
# -*-makefile-*-
-# $Header: /cvsroot/pgsql/src/Makefile.global.in,v 1.159 2003/01/06 03:18:26 momjian Exp $
+# $Header: /cvsroot/pgsql/src/Makefile.global.in,v 1.160 2003/03/29 11:31:51 petere Exp $
#------------------------------------------------------------------------------
# All PostgreSQL makefiles include this file and use the variables it sets,
LDFLAGS += $(rpath)
endif
-HAVE_IPV6 = @HAVE_IPV6@
##########################################################################
#
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/libpq/ip.c,v 1.2 2003/01/09 14:35:03 petere Exp $
+ * $Header: /cvsroot/pgsql/src/backend/libpq/ip.c,v 1.3 2003/03/29 11:31:51 petere Exp $
*
* This file and the IPV6 implementation were initially provided by
* Nigel Kukard <nkukard@lbsd.net>, Linux Based Systems Design
#define LOG stderr
#endif
-#if defined(HAVE_UNIX_SOCKETS) && defined(HAVE_IPV6)
+#if defined(HAVE_UNIX_SOCKETS)
static int getaddrinfo_unix(const char *path, const struct addrinfo *hintsp,
- struct addrinfo **result);
+ struct addrinfo **result);
#endif /* HAVE_UNIX_SOCKETS */
/*
*/
int
getaddrinfo2(const char *hostname, const char *servname,
-#ifdef HAVE_IPV6
const struct addrinfo *hintp, struct addrinfo **result)
-#else
- int family, SockAddr *result)
-#endif
{
#ifdef HAVE_UNIX_SOCKETS
-#ifdef HAVE_IPV6
if (hintp != NULL && hintp->ai_family == AF_UNIX)
return getaddrinfo_unix(servname, hintp, result);
-#else
- if (family == AF_UNIX)
- return 0;
-#endif
else
{
#endif /* HAVE_UNIX_SOCKETS */
-#ifdef HAVE_IPV6
/* NULL has special meaning to getaddrinfo */
return getaddrinfo((!hostname || hostname[0] == '\0') ? NULL : hostname,
servname, hintp, result);
-#else
- if (hostname[0] == '\0')
- result->in.sin_addr.s_addr = htonl(INADDR_ANY);
- else
- {
- struct hostent *hp;
-
- hp = gethostbyname(hostname);
- if ((hp == NULL) || (hp->h_addrtype != AF_INET))
- {
- elog(LOG, "getaddrinfo2: gethostbyname(%s) failed\n", hostname);
- return STATUS_ERROR;
- }
- memmove((char *) &(result->in.sin_addr), (char *) hp->h_addr,
- hp->h_length);
- }
-
- result->in.sin_port = htons((unsigned short)atoi(servname));
- return 0;
-#endif /* HAVE_IPV6 */
-
#ifdef HAVE_UNIX_SOCKETS
}
#endif /* HAVE_UNIX_SOCKETS */
/*
* freeaddrinfo2 - free IPv6 addrinfo structures
*/
-#ifdef HAVE_IPV6
void
freeaddrinfo2(int hint_ai_family, struct addrinfo *ai)
{
#endif /* HAVE_UNIX_SOCKETS */
freeaddrinfo(ai);
}
-#endif
-#if defined(HAVE_UNIX_SOCKETS) && defined(HAVE_IPV6)
+#if defined(HAVE_UNIX_SOCKETS)
/* -------
* getaddrinfo_unix - get unix socket info using IPv6
*
*/
static int
getaddrinfo_unix(const char *path, const struct addrinfo *hintsp,
- struct addrinfo **result)
+ struct addrinfo **result)
{
struct addrinfo hints;
struct addrinfo *aip;
if (hints.ai_socktype == 0)
hints.ai_socktype = SOCK_STREAM;
- if (!(hints.ai_family == AF_UNIX))
+ if (hints.ai_family != AF_UNIX)
{
- elog(LOG, "hints.ai_family is invalied getaddrinfo_unix()\n");
+ elog(LOG, "hints.ai_family is invalid in getaddrinfo_unix()\n");
return EAI_ADDRFAMILY;
}
return 0;
}
-#endif /* HAVE_UNIX_SOCKETS && HAVE_IPV6 */
+#endif /* HAVE_UNIX_SOCKETS */
/* ----------
* SockAddr_ntop - set IP address string from SockAddr
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Id: pqcomm.c,v 1.147 2003/01/25 05:19:46 tgl Exp $
+ * $Id: pqcomm.c,v 1.148 2003/03/29 11:31:51 petere Exp $
*
*-------------------------------------------------------------------------
*/
static int Setup_AF_UNIX(void);
#endif /* HAVE_UNIX_SOCKETS */
-#ifdef HAVE_IPV6
-#define FREEADDRINFO2(family, addrs) freeaddrinfo2((family), (addrs))
-#else
-/* do nothing */
-#define FREEADDRINFO2(family, addrs) do {} while (0)
-#endif
-
/*
* Configuration options
int ret;
char portNumberStr[64];
char *service;
-
- /*
- * IPv6 address lookups use a hint structure, while IPv4 creates an
- * address structure directly.
- */
-
-#ifdef HAVE_IPV6
struct addrinfo *addrs = NULL;
struct addrinfo hint;
hint.ai_family = family;
hint.ai_flags = AI_PASSIVE;
hint.ai_socktype = SOCK_STREAM;
-#else
- SockAddr saddr;
- size_t len;
-
- Assert(family == AF_INET || family == AF_UNIX);
-
- /* Initialize address structure */
- MemSet((char *) &saddr, 0, sizeof(saddr));
- saddr.sa.sa_family = family;
-#endif /* HAVE_IPV6 */
#ifdef HAVE_UNIX_SOCKETS
if (family == AF_UNIX)
if (Lock_AF_UNIX(portNumber, unixSocketName) != STATUS_OK)
return STATUS_ERROR;
service = sock_path;
-#ifndef HAVE_IPV6
- UNIXSOCK_PATH(saddr.un, portNumber, unixSocketName);
- len = UNIXSOCK_LEN(saddr.un);
-#endif
}
else
#endif /* HAVE_UNIX_SOCKETS */
{
snprintf(portNumberStr, sizeof(portNumberStr), "%d", portNumber);
service = portNumberStr;
-#ifndef HAVE_IPV6
- len = sizeof(saddr.in);
-#endif
}
- /* Look up name using IPv6 or IPv4 routines */
-#ifdef HAVE_IPV6
ret = getaddrinfo2(hostName, service, &hint, &addrs);
if (ret || addrs == NULL)
-#else
- ret = getaddrinfo2(hostName, service, family, &saddr);
- if (ret)
-#endif
{
elog(LOG, "server socket failure: getaddrinfo2()%s: %s",
-#ifdef HAVE_IPV6
(family == AF_INET6) ? " using IPv6" : "", gai_strerror(ret));
if (addrs != NULL)
- FREEADDRINFO2(hint.ai_family, addrs);
-#else
- "", hostName);
-#endif
+ freeaddrinfo2(hint.ai_family, addrs);
return STATUS_ERROR;
}
{
elog(LOG, "server socket failure: socket(): %s",
strerror(errno));
- FREEADDRINFO2(hint.ai_family, addrs);
+ freeaddrinfo2(hint.ai_family, addrs);
return STATUS_ERROR;
}
{
elog(LOG, "server socket failure: setsockopt(SO_REUSEADDR): %s",
strerror(errno));
- FREEADDRINFO2(hint.ai_family, addrs);
+ freeaddrinfo2(hint.ai_family, addrs);
return STATUS_ERROR;
}
}
-#ifdef HAVE_IPV6
Assert(addrs->ai_next == NULL && addrs->ai_family == family);
err = bind(fd, addrs->ai_addr, addrs->ai_addrlen);
-#else
- err = bind(fd, (struct sockaddr *) &saddr.sa, len);
-#endif
if (err < 0)
{
elog(LOG, "server socket failure: bind(): %s\n"
sock_path);
else
elog(LOG, "\tIf not, wait a few seconds and retry.");
- FREEADDRINFO2(hint.ai_family, addrs);
+ freeaddrinfo2(hint.ai_family, addrs);
return STATUS_ERROR;
}
{
if (Setup_AF_UNIX() != STATUS_OK)
{
- FREEADDRINFO2(hint.ai_family, addrs);
+ freeaddrinfo2(hint.ai_family, addrs);
return STATUS_ERROR;
}
}
{
elog(LOG, "server socket failure: listen(): %s",
strerror(errno));
- FREEADDRINFO2(hint.ai_family, addrs);
+ freeaddrinfo2(hint.ai_family, addrs);
return STATUS_ERROR;
}
*fdP = fd;
- FREEADDRINFO2(hint.ai_family, addrs);
+ freeaddrinfo2(hint.ai_family, addrs);
return STATUS_OK;
}
--- /dev/null
+/* $Header: /cvsroot/pgsql/src/include/getaddrinfo.h,v 1.1 2003/03/29 11:31:51 petere Exp $ */
+
+#ifndef GETADDRINFO_H
+#define GETADDRINFO_H
+
+#include "c.h"
+#include <netdb.h>
+
+
+struct addrinfo {
+ int ai_flags;
+ int ai_family;
+ int ai_socktype;
+ int ai_protocol;
+ size_t ai_addrlen;
+ struct sockaddr *ai_addr;
+ char *ai_canonname;
+ struct addrinfo *ai_next;
+};
+
+
+int getaddrinfo(const char *node, const char *service,
+ const struct addrinfo *hints, struct addrinfo **res);
+void freeaddrinfo(struct addrinfo *res);
+const char *gai_strerror(int errcode);
+
+
+#define EAI_BADFLAGS -1
+#define EAI_NONAME -2
+#define EAI_AGAIN -3
+#define EAI_FAIL -4
+#define EAI_NODATA -5
+#define EAI_FAMILY -6
+#define EAI_SOCKTYPE -7
+#define EAI_SERVICE -8
+#define EAI_ADDRFAMILY -9
+#define EAI_MEMORY -10
+#define EAI_SYSTEM -11
+
+#define AI_PASSIVE 0x0001
+#define AI_NUMERICHOST 0x0004
+
+#endif /* GETADDRINFO_H */
#ifndef IP_H
#define IP_H
+#include "c.h"
#include <sys/socket.h>
#include <netdb.h>
#include "libpq/pqcomm.h"
+#ifndef HAVE_GETADDRINFO
+#include "getaddrinfo.h"
+#endif
-#ifdef HAVE_IPV6
-void freeaddrinfo2(int hint_ai_family, struct addrinfo *ai);
int getaddrinfo2(const char *hostname, const char *servname,
- const struct addrinfo *hintp, struct addrinfo **result);
-#else
-int getaddrinfo2(const char *hostname, const char *servname,
- int family, SockAddr *result);
-#endif
+ const struct addrinfo *hintp, struct addrinfo **result);
+void freeaddrinfo2(int hint_ai_family, struct addrinfo *ai);
char *SockAddr_ntop(const SockAddr *sa, char *dst, size_t cnt, int v4conv);
int SockAddr_pton(SockAddr *sa, const char *src);
* or in pg_config.h afterwards. Of course, if you edit pg_config.h, then your
* changes will be overwritten the next time you run configure.
*
- * $Id: pg_config.h.in,v 1.41 2003/03/06 03:16:55 tgl Exp $
+ * $Id: pg_config.h.in,v 1.42 2003/03/29 11:31:51 petere Exp $
*/
#ifndef PG_CONFIG_H
#undef HAVE_FP_CLASS_D
#undef HAVE_CLASS
+/* Set to 1 if you have getaddrinfo() */
+#undef HAVE_GETADDRINFO
+
/* Set to 1 if you have gethostname() */
#undef HAVE_GETHOSTNAME
#
# Copyright (c) 1994, Regents of the University of California
#
-# $Header: /cvsroot/pgsql/src/interfaces/libpq/Makefile,v 1.73 2003/02/03 14:24:07 momjian Exp $
+# $Header: /cvsroot/pgsql/src/interfaces/libpq/Makefile,v 1.74 2003/03/29 11:31:51 petere Exp $
#
#-------------------------------------------------------------------------
OBJS= fe-auth.o fe-connect.o fe-exec.o fe-misc.o fe-print.o fe-lobj.o \
pqexpbuffer.o dllist.o pqsignal.o fe-secure.o wchar.o encnames.o ip.o \
md5.o \
- $(filter inet_aton.o snprintf.o strerror.o, $(LIBOBJS))
+ $(filter getaddrinfo.o inet_aton.o snprintf.o strerror.o, $(LIBOBJS))
# Add libraries that libpq depends (or might depend) on into the
# symlink the source files in here and build our own object file.
# this only gets done if configure finds system doesn't have inet_aton()
-inet_aton.c snprintf.c strerror.c: %.c : $(top_srcdir)/src/port/%.c
+getaddrinfo.c inet_aton.c snprintf.c strerror.c: %.c : $(top_srcdir)/src/port/%.c
rm -f $@ && $(LN_S) $< .
encnames.c wchar.c : % : $(backend_src)/utils/mb/%
clean distclean maintainer-clean: clean-lib
rm -f $(OBJS) dllist.c md5.c ip.c wchar.c encnames.c
- rm -f $(OBJS) inet_aton.c snprintf.c strerror.c
+ rm -f $(OBJS) getaddrinfo.c inet_aton.c snprintf.c strerror.c
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-connect.c,v 1.228 2003/03/20 06:23:30 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-connect.c,v 1.229 2003/03/29 11:31:51 petere Exp $
*
*-------------------------------------------------------------------------
*/
#include "mb/pg_wchar.h"
-#ifdef HAVE_IPV6
-#define FREEADDRINFO2(family, addrs) freeaddrinfo2((family), (addrs))
-#else
-/* do nothing */
-#define FREEADDRINFO2(family, addrs) do {} while (0)
-#endif
-
#ifdef WIN32
static int
inet_aton(const char *cp, struct in_addr * inp)
StartupPacket np; /* Used to negotiate SSL connection */
char SSLok;
#endif
-#ifdef HAVE_IPV6
struct addrinfo *addrs = NULL;
struct addrinfo *addr_cur = NULL;
struct addrinfo hint;
/* Initialize hint structure */
MemSet(&hint, 0, sizeof(hint));
hint.ai_socktype = SOCK_STREAM;
-#else
- int family = -1;
-#endif
if (!conn)
return 0;
/*
* Set up the connection to postmaster/backend.
- *
- * This code is confusing because IPv6 creates a hint structure
- * that is passed to getaddrinfo2(), which returns a list of address
- * structures that are looped through, while IPv4 creates an address
- * structure directly.
*/
MemSet((char *) &conn->raddr, 0, sizeof(conn->raddr));
if (conn->pghostaddr != NULL && conn->pghostaddr[0] != '\0')
{
-#ifdef HAVE_IPV6
+ /* Using pghostaddr avoids a hostname lookup */
node = conn->pghostaddr;
hint.ai_family = AF_UNSPEC;
-#else
- /* Using pghostaddr avoids a hostname lookup */
- struct in_addr addr;
-
- if (!inet_aton(conn->pghostaddr, &addr))
- {
- printfPQExpBuffer(&conn->errorMessage,
- libpq_gettext("invalid host address: %s\n"),
- conn->pghostaddr);
- goto connect_errReturn;
- }
-
- family = AF_INET;
-
- memcpy((char *) &(conn->raddr.in.sin_addr),
- (char *) &addr, sizeof(addr));
-#endif
+ hint.ai_flags = AI_NUMERICHOST;
}
else if (conn->pghost != NULL && conn->pghost[0] != '\0')
{
-#ifdef HAVE_IPV6
+ /* Using pghost, so we have to look-up the hostname */
node = conn->pghost;
hint.ai_family = AF_UNSPEC;
-#else
- /* Using pghost, so we have to look-up the hostname */
- if (getaddrinfo2(conn->pghost, portstr, family, &conn->raddr) != 0)
- goto connect_errReturn;
-
- family = AF_INET;
-#endif
}
else
{
+ /* pghostaddr and pghost are NULL, so use Unix domain socket */
#ifdef HAVE_UNIX_SOCKETS
-#ifdef HAVE_IPV6
node = unix_node;
hint.ai_family = AF_UNIX;
-#else
- /* pghostaddr and pghost are NULL, so use Unix domain socket */
- family = AF_UNIX;
-#endif
-#endif /* HAVE_UNIX_SOCKETS */
- }
-
-#ifndef HAVE_IPV6
- /* Set family */
- conn->raddr.sa.sa_family = family;
-#endif
-
-#ifdef HAVE_IPV6
- if (hint.ai_family == AF_UNSPEC)
- {
- /* do nothing */
- }
-#else
- if (family == AF_INET)
- {
- conn->raddr.in.sin_port = htons((unsigned short) (portnum));
- conn->raddr_len = sizeof(struct sockaddr_in);
- }
-#endif
- else
- {
-#ifdef HAVE_UNIX_SOCKETS
UNIXSOCK_PATH(conn->raddr.un, portnum, conn->pgunixsocket);
conn->raddr_len = UNIXSOCK_LEN(conn->raddr.un);
StrNCpy(portstr, conn->raddr.un.sun_path, sizeof(portstr));
#endif /* HAVE_UNIX_SOCKETS */
}
-#ifdef HAVE_IPV6
/* Use getaddrinfo2() to resolve the address */
ret = getaddrinfo2(node, portstr, &hint, &addrs);
if (ret || addrs == NULL)
gai_strerror(ret));
goto connect_errReturn;
}
-#endif
/*
- * For IPV6 we loop over the possible addresses returned by
- * getaddrinfo2(), and fail only when they all fail (reporting the
- * error returned for the *last* alternative, which may not be what
- * users expect :-(). Otherwise, there is no true loop here.
+ * We loop over the possible addresses returned by getaddrinfo2(),
+ * and fail only when they all fail (reporting the error returned
+ * for the *last* alternative, which may not be what users expect
+ * :-().
*
* In either case, we never actually fall out of the loop; the
* only exits are via "break" or "goto connect_errReturn". Thus,
* there is no exit test in the for().
*/
- for (
-#ifdef HAVE_IPV6
- addr_cur = addrs; ; addr_cur = addr_cur->ai_next
-#else
- ;;
-#endif
- )
+ for (addr_cur = addrs; ; addr_cur = addr_cur->ai_next)
{
/* Open a socket */
-#ifdef HAVE_IPV6
conn->sock = socket(addr_cur->ai_family, SOCK_STREAM,
addr_cur->ai_protocol);
-#else
- conn->sock = socket(family, SOCK_STREAM, 0);
-#endif
if (conn->sock < 0)
{
-#ifdef HAVE_IPV6
/* ignore socket() failure if we have more addrs to try */
if (addr_cur->ai_next != NULL)
continue;
-#endif
printfPQExpBuffer(&conn->errorMessage,
libpq_gettext("could not create socket: %s\n"),
SOCK_STRERROR(SOCK_ERRNO));
* using SSL, then we need the blocking I/O (XXX Can this be fixed?).
*/
-#ifdef HAVE_IPV6
if (isAF_INETx(addr_cur->ai_family))
-#else
- if (isAF_INETx(family))
-#endif
{
if (!connectNoDelay(conn))
goto connect_errReturn;
* ----------
*/
retry1:
-#ifdef HAVE_IPV6
if (connect(conn->sock, addr_cur->ai_addr, addr_cur->ai_addrlen) < 0)
-#else
- if (connect(conn->sock, &conn->raddr.sa, conn->raddr_len) < 0)
-#endif
{
if (SOCK_ERRNO == EINTR)
/* Interrupted system call - we'll just try again */
* This connection failed. We need to close the socket,
* and either loop to try the next address or report an error.
*/
-#ifdef HAVE_IPV6
/* ignore connect() failure if we have more addrs to try */
if (addr_cur->ai_next != NULL)
{
conn->sock = -1;
continue;
}
-#endif
+ /* copy failed address for error report */
+ memcpy(&conn->raddr, addr_cur->ai_addr, addr_cur->ai_addrlen);
+ conn->raddr_len = addr_cur->ai_addrlen;
connectFailureMessage(conn, SOCK_ERRNO);
goto connect_errReturn;
} /* loop over addrs */
-#ifdef HAVE_IPV6
/* Remember the successfully opened address alternative */
memcpy(&conn->raddr, addr_cur->ai_addr, addr_cur->ai_addrlen);
conn->raddr_len = addr_cur->ai_addrlen;
/* and release the address list */
- FREEADDRINFO2(hint.ai_family, addrs);
+ freeaddrinfo2(hint.ai_family, addrs);
addrs = NULL;
-#endif
#ifdef USE_SSL
/* Attempt to negotiate SSL usage */
conn->sock = -1;
}
conn->status = CONNECTION_BAD;
-#ifdef HAVE_IPV6
if (addrs != NULL)
- FREEADDRINFO2(hint.ai_family, addrs);
-#endif
+ freeaddrinfo2(hint.ai_family, addrs);
return 0;
}
--- /dev/null
+/* $Header: /cvsroot/pgsql/src/port/getaddrinfo.c,v 1.1 2003/03/29 11:31:52 petere Exp $ */
+
+#include "c.h"
+#include "getaddrinfo.h"
+#include <netdb.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+
+int
+getaddrinfo(const char *node, const char *service,
+ const struct addrinfo *hints,
+ struct addrinfo **res)
+{
+ struct addrinfo *ai;
+ struct sockaddr_in sin, *psin;
+
+ if (!hints || (hints->ai_family != AF_INET && hints->ai_family != AF_UNSPEC))
+ return EAI_FAMILY;
+
+ if (hints->ai_socktype != SOCK_STREAM)
+ return EAI_SOCKTYPE;
+
+ if (!node && !service)
+ return EAI_NONAME;
+
+ if (node)
+ {
+ if (node[0] == '\0')
+ sin.sin_addr.s_addr = htonl(INADDR_ANY);
+ else if (hints->ai_flags & AI_NUMERICHOST)
+ {
+ inet_aton(node, &sin.sin_addr);
+ }
+ else
+ {
+ struct hostent *hp;
+
+ hp = gethostbyname(node);
+ if (hp == NULL)
+ {
+ switch (h_errno)
+ {
+ case HOST_NOT_FOUND:
+ return EAI_NONAME;
+ case NO_DATA:
+ return EAI_NODATA;
+ case TRY_AGAIN:
+ return EAI_AGAIN;
+ case NO_RECOVERY:
+ default:
+ return EAI_FAIL;
+ }
+ }
+ if (hp->h_addrtype != AF_INET)
+ return EAI_ADDRFAMILY;
+
+ memmove(&(sin.sin_addr), hp->h_addr, hp->h_length);
+ }
+ }
+ else
+ {
+ if (hints->ai_flags & AI_PASSIVE)
+ sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+ }
+
+ if (service)
+ sin.sin_port = htons((unsigned short)atoi(service));
+
+ ai = malloc(sizeof(*ai));
+ if (!ai)
+ return EAI_MEMORY;
+ psin = malloc(sizeof(*psin));
+ if (!psin)
+ {
+ free(ai);
+ return EAI_MEMORY;
+ }
+
+ memcpy(psin, &sin, sizeof(sin));
+
+ ai->ai_family = hints->ai_family;
+ ai->ai_socktype = hints->ai_socktype;
+ ai->ai_protocol = hints->ai_protocol;
+ ai->ai_addrlen = sizeof(*psin);
+ ai->ai_addr = (struct sockaddr *) psin;
+ ai->ai_canonname = NULL;
+ ai->ai_next = NULL;
+
+ *res = ai;
+
+ return 0;
+}
+
+
+void
+freeaddrinfo(struct addrinfo *res)
+{
+ if (res)
+ {
+ if (res->ai_addr)
+ free(res->ai_addr);
+ free(res);
+ }
+}
+
+
+const char*
+gai_strerror(int errcode)
+{
+ int hcode;
+
+ switch (errcode)
+ {
+ case EAI_NONAME:
+ hcode = HOST_NOT_FOUND;
+ break;
+ case EAI_NODATA:
+ hcode = NO_DATA;
+ break;
+ case EAI_AGAIN:
+ hcode = TRY_AGAIN;
+ break;
+ case EAI_FAIL:
+ default:
+ hcode = NO_RECOVERY;
+ break;
+ }
+
+ return hstrerror(hcode);
+}