mirror of
https://github.com/postgres/postgres.git
synced 2025-06-05 23:56:58 +03:00
Simplify the socket handling code by supplying a replacement getaddrinfo()
function if the OS doesn't provide one.
This commit is contained in:
parent
bf7ca0a769
commit
82a91eb54e
140
configure
vendored
140
configure
vendored
@ -10321,73 +10321,7 @@ fi
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
# This exports HAVE_IPV6 to both C files and Makefiles
|
echo "$as_me:$LINENO: checking for struct sockaddr_in6" >&5
|
||||||
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 $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) ();
|
|
||||||
|
|
||||||
#ifdef F77_DUMMY_MAIN
|
|
||||||
# ifdef __cplusplus
|
|
||||||
extern "C"
|
|
||||||
# endif
|
|
||||||
int F77_DUMMY_MAIN() { return 1; }
|
|
||||||
#endif
|
|
||||||
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
|
|
||||||
|
|
||||||
;
|
|
||||||
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
|
|
||||||
ac_status=$?
|
|
||||||
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
|
||||||
(exit $ac_status); } &&
|
|
||||||
{ 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_func_getaddrinfo=yes
|
|
||||||
else
|
|
||||||
echo "$as_me: failed program was:" >&5
|
|
||||||
cat conftest.$ac_ext >&5
|
|
||||||
ac_cv_func_getaddrinfo=no
|
|
||||||
fi
|
|
||||||
rm -f conftest.$ac_objext conftest$ac_exeext 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
|
echo $ECHO_N "checking for struct sockaddr_in6... $ECHO_C" >&6
|
||||||
if test "${ac_cv_type_struct_sockaddr_in6+set}" = set; then
|
if test "${ac_cv_type_struct_sockaddr_in6+set}" = set; then
|
||||||
echo $ECHO_N "(cached) $ECHO_C" >&6
|
echo $ECHO_N "(cached) $ECHO_C" >&6
|
||||||
@ -10438,7 +10372,72 @@ fi
|
|||||||
echo "$as_me:$LINENO: result: $ac_cv_type_struct_sockaddr_in6" >&5
|
echo "$as_me:$LINENO: result: $ac_cv_type_struct_sockaddr_in6" >&5
|
||||||
echo "${ECHO_T}$ac_cv_type_struct_sockaddr_in6" >&6
|
echo "${ECHO_T}$ac_cv_type_struct_sockaddr_in6" >&6
|
||||||
if test $ac_cv_type_struct_sockaddr_in6 = yes; then
|
if test $ac_cv_type_struct_sockaddr_in6 = yes; then
|
||||||
HAVE_IPV6="yes"; cat >>confdefs.h <<\_ACEOF
|
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"
|
||||||
|
/* 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
|
||||||
|
extern "C"
|
||||||
|
# endif
|
||||||
|
int F77_DUMMY_MAIN() { return 1; }
|
||||||
|
#endif
|
||||||
|
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_inet_ntop) || defined (__stub___inet_ntop)
|
||||||
|
choke me
|
||||||
|
#else
|
||||||
|
f = inet_ntop;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
;
|
||||||
|
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
|
||||||
|
ac_status=$?
|
||||||
|
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||||
|
(exit $ac_status); } &&
|
||||||
|
{ 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_func_inet_ntop=yes
|
||||||
|
else
|
||||||
|
echo "$as_me: failed program was:" >&5
|
||||||
|
cat conftest.$ac_ext >&5
|
||||||
|
ac_cv_func_inet_ntop=no
|
||||||
|
fi
|
||||||
|
rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
|
||||||
|
fi
|
||||||
|
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
|
#define HAVE_IPV6 1
|
||||||
_ACEOF
|
_ACEOF
|
||||||
|
|
||||||
@ -10447,7 +10446,6 @@ fi
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
echo "$as_me:$LINENO: checking for PS_STRINGS" >&5
|
echo "$as_me:$LINENO: checking for PS_STRINGS" >&5
|
||||||
echo $ECHO_N "checking for PS_STRINGS... $ECHO_C" >&6
|
echo $ECHO_N "checking for PS_STRINGS... $ECHO_C" >&6
|
||||||
if test "${pgac_cv_var_PS_STRINGS+set}" = set; then
|
if test "${pgac_cv_var_PS_STRINGS+set}" = set; then
|
||||||
@ -10952,7 +10950,8 @@ fi
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
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
|
do
|
||||||
as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
|
as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
|
||||||
echo "$as_me:$LINENO: checking for $ac_func" >&5
|
echo "$as_me:$LINENO: checking for $ac_func" >&5
|
||||||
@ -17013,7 +17012,6 @@ s,@python_moduleexecdir@,$python_moduleexecdir,;t t
|
|||||||
s,@python_includespec@,$python_includespec,;t t
|
s,@python_includespec@,$python_includespec,;t t
|
||||||
s,@python_libspec@,$python_libspec,;t t
|
s,@python_libspec@,$python_libspec,;t t
|
||||||
s,@LIBOBJS@,$LIBOBJS,;t t
|
s,@LIBOBJS@,$LIBOBJS,;t t
|
||||||
s,@HAVE_IPV6@,$HAVE_IPV6,;t t
|
|
||||||
s,@HPUXMATHLIB@,$HPUXMATHLIB,;t t
|
s,@HPUXMATHLIB@,$HPUXMATHLIB,;t t
|
||||||
s,@HAVE_POSIX_SIGNALS@,$HAVE_POSIX_SIGNALS,;t t
|
s,@HAVE_POSIX_SIGNALS@,$HAVE_POSIX_SIGNALS,;t t
|
||||||
s,@MSGFMT@,$MSGFMT,;t t
|
s,@MSGFMT@,$MSGFMT,;t t
|
||||||
|
16
configure.in
16
configure.in
@ -1,5 +1,5 @@
|
|||||||
dnl Process this file with autoconf to produce a configure script.
|
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
|
||||||
dnl Developers, please strive to achieve this order:
|
dnl Developers, please strive to achieve this order:
|
||||||
dnl
|
dnl
|
||||||
@ -791,14 +791,12 @@ AC_CHECK_FUNCS([cbrt dlopen fcvt fdatasync getpeereid memmove poll pstat setproc
|
|||||||
|
|
||||||
AC_CHECK_DECLS(fdatasync, [], [], [#include <unistd.h>])
|
AC_CHECK_DECLS(fdatasync, [], [], [#include <unistd.h>])
|
||||||
|
|
||||||
# This exports HAVE_IPV6 to both C files and Makefiles
|
AC_CHECK_TYPE([struct sockaddr_in6],
|
||||||
AC_CHECK_FUNC(getaddrinfo,
|
[AC_CHECK_FUNC(inet_ntop,
|
||||||
[AC_CHECK_TYPE(struct sockaddr_in6,
|
[AC_DEFINE(HAVE_IPV6, 1)])],
|
||||||
[HAVE_IPV6="yes"; AC_DEFINE(HAVE_IPV6, 1)],
|
[],
|
||||||
[],
|
|
||||||
[$ac_includes_default
|
[$ac_includes_default
|
||||||
#include <netinet/in.h>])])
|
#include <netinet/in.h>])
|
||||||
AC_SUBST(HAVE_IPV6)
|
|
||||||
|
|
||||||
AC_CACHE_CHECK([for PS_STRINGS], [pgac_cv_var_PS_STRINGS],
|
AC_CACHE_CHECK([for PS_STRINGS], [pgac_cv_var_PS_STRINGS],
|
||||||
[AC_TRY_LINK(
|
[AC_TRY_LINK(
|
||||||
@ -849,7 +847,7 @@ else
|
|||||||
AC_CHECK_FUNCS([fpclass fp_class fp_class_d class], [break])
|
AC_CHECK_FUNCS([fpclass fp_class fp_class_d class], [break])
|
||||||
fi
|
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
|
# BSD/OS & NetBSD use a custom fseeko/ftello built on fsetpos/fgetpos
|
||||||
# We override the previous test that said fseeko/ftello didn't exist
|
# We override the previous test that said fseeko/ftello didn't exist
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
# -*-makefile-*-
|
# -*-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,
|
# All PostgreSQL makefiles include this file and use the variables it sets,
|
||||||
@ -277,7 +277,6 @@ ifeq ($(enable_rpath), yes)
|
|||||||
LDFLAGS += $(rpath)
|
LDFLAGS += $(rpath)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
HAVE_IPV6 = @HAVE_IPV6@
|
|
||||||
|
|
||||||
##########################################################################
|
##########################################################################
|
||||||
#
|
#
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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
|
* This file and the IPV6 implementation were initially provided by
|
||||||
* Nigel Kukard <nkukard@lbsd.net>, Linux Based Systems Design
|
* Nigel Kukard <nkukard@lbsd.net>, Linux Based Systems Design
|
||||||
@ -44,9 +44,9 @@
|
|||||||
#define LOG stderr
|
#define LOG stderr
|
||||||
#endif
|
#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,
|
static int getaddrinfo_unix(const char *path, const struct addrinfo *hintsp,
|
||||||
struct addrinfo **result);
|
struct addrinfo **result);
|
||||||
#endif /* HAVE_UNIX_SOCKETS */
|
#endif /* HAVE_UNIX_SOCKETS */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -54,48 +54,17 @@ static int getaddrinfo_unix(const char *path, const struct addrinfo *hintsp,
|
|||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
getaddrinfo2(const char *hostname, const char *servname,
|
getaddrinfo2(const char *hostname, const char *servname,
|
||||||
#ifdef HAVE_IPV6
|
|
||||||
const struct addrinfo *hintp, struct addrinfo **result)
|
const struct addrinfo *hintp, struct addrinfo **result)
|
||||||
#else
|
|
||||||
int family, SockAddr *result)
|
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
#ifdef HAVE_UNIX_SOCKETS
|
#ifdef HAVE_UNIX_SOCKETS
|
||||||
#ifdef HAVE_IPV6
|
|
||||||
if (hintp != NULL && hintp->ai_family == AF_UNIX)
|
if (hintp != NULL && hintp->ai_family == AF_UNIX)
|
||||||
return getaddrinfo_unix(servname, hintp, result);
|
return getaddrinfo_unix(servname, hintp, result);
|
||||||
#else
|
|
||||||
if (family == AF_UNIX)
|
|
||||||
return 0;
|
|
||||||
#endif
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
#endif /* HAVE_UNIX_SOCKETS */
|
#endif /* HAVE_UNIX_SOCKETS */
|
||||||
#ifdef HAVE_IPV6
|
|
||||||
/* NULL has special meaning to getaddrinfo */
|
/* NULL has special meaning to getaddrinfo */
|
||||||
return getaddrinfo((!hostname || hostname[0] == '\0') ? NULL : hostname,
|
return getaddrinfo((!hostname || hostname[0] == '\0') ? NULL : hostname,
|
||||||
servname, hintp, result);
|
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
|
#ifdef HAVE_UNIX_SOCKETS
|
||||||
}
|
}
|
||||||
#endif /* HAVE_UNIX_SOCKETS */
|
#endif /* HAVE_UNIX_SOCKETS */
|
||||||
@ -105,7 +74,6 @@ getaddrinfo2(const char *hostname, const char *servname,
|
|||||||
/*
|
/*
|
||||||
* freeaddrinfo2 - free IPv6 addrinfo structures
|
* freeaddrinfo2 - free IPv6 addrinfo structures
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_IPV6
|
|
||||||
void
|
void
|
||||||
freeaddrinfo2(int hint_ai_family, struct addrinfo *ai)
|
freeaddrinfo2(int hint_ai_family, struct addrinfo *ai)
|
||||||
{
|
{
|
||||||
@ -126,10 +94,9 @@ freeaddrinfo2(int hint_ai_family, struct addrinfo *ai)
|
|||||||
#endif /* HAVE_UNIX_SOCKETS */
|
#endif /* HAVE_UNIX_SOCKETS */
|
||||||
freeaddrinfo(ai);
|
freeaddrinfo(ai);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#if defined(HAVE_UNIX_SOCKETS) && defined(HAVE_IPV6)
|
#if defined(HAVE_UNIX_SOCKETS)
|
||||||
/* -------
|
/* -------
|
||||||
* getaddrinfo_unix - get unix socket info using IPv6
|
* getaddrinfo_unix - get unix socket info using IPv6
|
||||||
*
|
*
|
||||||
@ -140,7 +107,7 @@ freeaddrinfo2(int hint_ai_family, struct addrinfo *ai)
|
|||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
getaddrinfo_unix(const char *path, const struct addrinfo *hintsp,
|
getaddrinfo_unix(const char *path, const struct addrinfo *hintsp,
|
||||||
struct addrinfo **result)
|
struct addrinfo **result)
|
||||||
{
|
{
|
||||||
struct addrinfo hints;
|
struct addrinfo hints;
|
||||||
struct addrinfo *aip;
|
struct addrinfo *aip;
|
||||||
@ -159,9 +126,9 @@ getaddrinfo_unix(const char *path, const struct addrinfo *hintsp,
|
|||||||
if (hints.ai_socktype == 0)
|
if (hints.ai_socktype == 0)
|
||||||
hints.ai_socktype = SOCK_STREAM;
|
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 EAI_ADDRFAMILY;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -197,7 +164,7 @@ getaddrinfo_unix(const char *path, const struct addrinfo *hintsp,
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif /* HAVE_UNIX_SOCKETS && HAVE_IPV6 */
|
#endif /* HAVE_UNIX_SOCKETS */
|
||||||
|
|
||||||
/* ----------
|
/* ----------
|
||||||
* SockAddr_ntop - set IP address string from SockAddr
|
* SockAddr_ntop - set IP address string from SockAddr
|
||||||
|
@ -29,7 +29,7 @@
|
|||||||
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* 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 $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -96,13 +96,6 @@ static int Lock_AF_UNIX(unsigned short portNumber, char *unixSocketName);
|
|||||||
static int Setup_AF_UNIX(void);
|
static int Setup_AF_UNIX(void);
|
||||||
#endif /* HAVE_UNIX_SOCKETS */
|
#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
|
* Configuration options
|
||||||
@ -208,13 +201,6 @@ StreamServerPort(int family, char *hostName, unsigned short portNumber,
|
|||||||
int ret;
|
int ret;
|
||||||
char portNumberStr[64];
|
char portNumberStr[64];
|
||||||
char *service;
|
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 *addrs = NULL;
|
||||||
struct addrinfo hint;
|
struct addrinfo hint;
|
||||||
|
|
||||||
@ -225,16 +211,6 @@ StreamServerPort(int family, char *hostName, unsigned short portNumber,
|
|||||||
hint.ai_family = family;
|
hint.ai_family = family;
|
||||||
hint.ai_flags = AI_PASSIVE;
|
hint.ai_flags = AI_PASSIVE;
|
||||||
hint.ai_socktype = SOCK_STREAM;
|
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
|
#ifdef HAVE_UNIX_SOCKETS
|
||||||
if (family == AF_UNIX)
|
if (family == AF_UNIX)
|
||||||
@ -242,38 +218,21 @@ StreamServerPort(int family, char *hostName, unsigned short portNumber,
|
|||||||
if (Lock_AF_UNIX(portNumber, unixSocketName) != STATUS_OK)
|
if (Lock_AF_UNIX(portNumber, unixSocketName) != STATUS_OK)
|
||||||
return STATUS_ERROR;
|
return STATUS_ERROR;
|
||||||
service = sock_path;
|
service = sock_path;
|
||||||
#ifndef HAVE_IPV6
|
|
||||||
UNIXSOCK_PATH(saddr.un, portNumber, unixSocketName);
|
|
||||||
len = UNIXSOCK_LEN(saddr.un);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif /* HAVE_UNIX_SOCKETS */
|
#endif /* HAVE_UNIX_SOCKETS */
|
||||||
{
|
{
|
||||||
snprintf(portNumberStr, sizeof(portNumberStr), "%d", portNumber);
|
snprintf(portNumberStr, sizeof(portNumberStr), "%d", portNumber);
|
||||||
service = portNumberStr;
|
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);
|
ret = getaddrinfo2(hostName, service, &hint, &addrs);
|
||||||
if (ret || addrs == NULL)
|
if (ret || addrs == NULL)
|
||||||
#else
|
|
||||||
ret = getaddrinfo2(hostName, service, family, &saddr);
|
|
||||||
if (ret)
|
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
elog(LOG, "server socket failure: getaddrinfo2()%s: %s",
|
elog(LOG, "server socket failure: getaddrinfo2()%s: %s",
|
||||||
#ifdef HAVE_IPV6
|
|
||||||
(family == AF_INET6) ? " using IPv6" : "", gai_strerror(ret));
|
(family == AF_INET6) ? " using IPv6" : "", gai_strerror(ret));
|
||||||
if (addrs != NULL)
|
if (addrs != NULL)
|
||||||
FREEADDRINFO2(hint.ai_family, addrs);
|
freeaddrinfo2(hint.ai_family, addrs);
|
||||||
#else
|
|
||||||
"", hostName);
|
|
||||||
#endif
|
|
||||||
return STATUS_ERROR;
|
return STATUS_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -281,7 +240,7 @@ StreamServerPort(int family, char *hostName, unsigned short portNumber,
|
|||||||
{
|
{
|
||||||
elog(LOG, "server socket failure: socket(): %s",
|
elog(LOG, "server socket failure: socket(): %s",
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
FREEADDRINFO2(hint.ai_family, addrs);
|
freeaddrinfo2(hint.ai_family, addrs);
|
||||||
return STATUS_ERROR;
|
return STATUS_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -292,17 +251,13 @@ StreamServerPort(int family, char *hostName, unsigned short portNumber,
|
|||||||
{
|
{
|
||||||
elog(LOG, "server socket failure: setsockopt(SO_REUSEADDR): %s",
|
elog(LOG, "server socket failure: setsockopt(SO_REUSEADDR): %s",
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
FREEADDRINFO2(hint.ai_family, addrs);
|
freeaddrinfo2(hint.ai_family, addrs);
|
||||||
return STATUS_ERROR;
|
return STATUS_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_IPV6
|
|
||||||
Assert(addrs->ai_next == NULL && addrs->ai_family == family);
|
Assert(addrs->ai_next == NULL && addrs->ai_family == family);
|
||||||
err = bind(fd, addrs->ai_addr, addrs->ai_addrlen);
|
err = bind(fd, addrs->ai_addr, addrs->ai_addrlen);
|
||||||
#else
|
|
||||||
err = bind(fd, (struct sockaddr *) &saddr.sa, len);
|
|
||||||
#endif
|
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
{
|
{
|
||||||
elog(LOG, "server socket failure: bind(): %s\n"
|
elog(LOG, "server socket failure: bind(): %s\n"
|
||||||
@ -313,7 +268,7 @@ StreamServerPort(int family, char *hostName, unsigned short portNumber,
|
|||||||
sock_path);
|
sock_path);
|
||||||
else
|
else
|
||||||
elog(LOG, "\tIf not, wait a few seconds and retry.");
|
elog(LOG, "\tIf not, wait a few seconds and retry.");
|
||||||
FREEADDRINFO2(hint.ai_family, addrs);
|
freeaddrinfo2(hint.ai_family, addrs);
|
||||||
return STATUS_ERROR;
|
return STATUS_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -322,7 +277,7 @@ StreamServerPort(int family, char *hostName, unsigned short portNumber,
|
|||||||
{
|
{
|
||||||
if (Setup_AF_UNIX() != STATUS_OK)
|
if (Setup_AF_UNIX() != STATUS_OK)
|
||||||
{
|
{
|
||||||
FREEADDRINFO2(hint.ai_family, addrs);
|
freeaddrinfo2(hint.ai_family, addrs);
|
||||||
return STATUS_ERROR;
|
return STATUS_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -342,12 +297,12 @@ StreamServerPort(int family, char *hostName, unsigned short portNumber,
|
|||||||
{
|
{
|
||||||
elog(LOG, "server socket failure: listen(): %s",
|
elog(LOG, "server socket failure: listen(): %s",
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
FREEADDRINFO2(hint.ai_family, addrs);
|
freeaddrinfo2(hint.ai_family, addrs);
|
||||||
return STATUS_ERROR;
|
return STATUS_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
*fdP = fd;
|
*fdP = fd;
|
||||||
FREEADDRINFO2(hint.ai_family, addrs);
|
freeaddrinfo2(hint.ai_family, addrs);
|
||||||
return STATUS_OK;
|
return STATUS_OK;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
43
src/include/getaddrinfo.h
Normal file
43
src/include/getaddrinfo.h
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
/* $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 */
|
@ -1,18 +1,17 @@
|
|||||||
#ifndef IP_H
|
#ifndef IP_H
|
||||||
#define IP_H
|
#define IP_H
|
||||||
|
#include "c.h"
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
#include "libpq/pqcomm.h"
|
#include "libpq/pqcomm.h"
|
||||||
|
#ifndef HAVE_GETADDRINFO
|
||||||
#ifdef HAVE_IPV6
|
#include "getaddrinfo.h"
|
||||||
void freeaddrinfo2(int hint_ai_family, struct addrinfo *ai);
|
|
||||||
int getaddrinfo2(const char *hostname, const char *servname,
|
|
||||||
const struct addrinfo *hintp, struct addrinfo **result);
|
|
||||||
#else
|
|
||||||
int getaddrinfo2(const char *hostname, const char *servname,
|
|
||||||
int family, SockAddr *result);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
int getaddrinfo2(const char *hostname, const char *servname,
|
||||||
|
const struct addrinfo *hintp, struct addrinfo **result);
|
||||||
|
void freeaddrinfo2(int hint_ai_family, struct addrinfo *ai);
|
||||||
|
|
||||||
char *SockAddr_ntop(const SockAddr *sa, char *dst, size_t cnt, int v4conv);
|
char *SockAddr_ntop(const SockAddr *sa, char *dst, size_t cnt, int v4conv);
|
||||||
int SockAddr_pton(SockAddr *sa, const char *src);
|
int SockAddr_pton(SockAddr *sa, const char *src);
|
||||||
int isAF_INETx(const int family);
|
int isAF_INETx(const int family);
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
* or in pg_config.h afterwards. Of course, if you edit pg_config.h, then your
|
* 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.
|
* 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
|
#ifndef PG_CONFIG_H
|
||||||
@ -459,6 +459,9 @@
|
|||||||
#undef HAVE_FP_CLASS_D
|
#undef HAVE_FP_CLASS_D
|
||||||
#undef HAVE_CLASS
|
#undef HAVE_CLASS
|
||||||
|
|
||||||
|
/* Set to 1 if you have getaddrinfo() */
|
||||||
|
#undef HAVE_GETADDRINFO
|
||||||
|
|
||||||
/* Set to 1 if you have gethostname() */
|
/* Set to 1 if you have gethostname() */
|
||||||
#undef HAVE_GETHOSTNAME
|
#undef HAVE_GETHOSTNAME
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
#
|
#
|
||||||
# Copyright (c) 1994, Regents of the University of California
|
# 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 $
|
||||||
#
|
#
|
||||||
#-------------------------------------------------------------------------
|
#-------------------------------------------------------------------------
|
||||||
|
|
||||||
@ -23,7 +23,7 @@ override CPPFLAGS := -I$(srcdir) $(CPPFLAGS) -DFRONTEND -DSYSCONFDIR='"$(sysconf
|
|||||||
OBJS= fe-auth.o fe-connect.o fe-exec.o fe-misc.o fe-print.o fe-lobj.o \
|
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 \
|
pqexpbuffer.o dllist.o pqsignal.o fe-secure.o wchar.o encnames.o ip.o \
|
||||||
md5.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
|
# Add libraries that libpq depends (or might depend) on into the
|
||||||
@ -54,7 +54,7 @@ ip.c: $(backend_src)/libpq/ip.c
|
|||||||
# symlink the source files in here and build our own object file.
|
# 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()
|
# 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) $< .
|
rm -f $@ && $(LN_S) $< .
|
||||||
|
|
||||||
encnames.c wchar.c : % : $(backend_src)/utils/mb/%
|
encnames.c wchar.c : % : $(backend_src)/utils/mb/%
|
||||||
@ -75,4 +75,4 @@ uninstall: uninstall-lib
|
|||||||
|
|
||||||
clean distclean maintainer-clean: clean-lib
|
clean distclean maintainer-clean: clean-lib
|
||||||
rm -f $(OBJS) dllist.c md5.c ip.c wchar.c encnames.c
|
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
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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 $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -50,13 +50,6 @@
|
|||||||
#include "mb/pg_wchar.h"
|
#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
|
#ifdef WIN32
|
||||||
static int
|
static int
|
||||||
inet_aton(const char *cp, struct in_addr * inp)
|
inet_aton(const char *cp, struct in_addr * inp)
|
||||||
@ -803,7 +796,6 @@ connectDBStart(PGconn *conn)
|
|||||||
StartupPacket np; /* Used to negotiate SSL connection */
|
StartupPacket np; /* Used to negotiate SSL connection */
|
||||||
char SSLok;
|
char SSLok;
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_IPV6
|
|
||||||
struct addrinfo *addrs = NULL;
|
struct addrinfo *addrs = NULL;
|
||||||
struct addrinfo *addr_cur = NULL;
|
struct addrinfo *addr_cur = NULL;
|
||||||
struct addrinfo hint;
|
struct addrinfo hint;
|
||||||
@ -814,9 +806,6 @@ connectDBStart(PGconn *conn)
|
|||||||
/* Initialize hint structure */
|
/* Initialize hint structure */
|
||||||
MemSet(&hint, 0, sizeof(hint));
|
MemSet(&hint, 0, sizeof(hint));
|
||||||
hint.ai_socktype = SOCK_STREAM;
|
hint.ai_socktype = SOCK_STREAM;
|
||||||
#else
|
|
||||||
int family = -1;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!conn)
|
if (!conn)
|
||||||
return 0;
|
return 0;
|
||||||
@ -835,11 +824,6 @@ connectDBStart(PGconn *conn)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Set up the connection to postmaster/backend.
|
* 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));
|
MemSet((char *) &conn->raddr, 0, sizeof(conn->raddr));
|
||||||
@ -853,73 +837,23 @@ connectDBStart(PGconn *conn)
|
|||||||
|
|
||||||
if (conn->pghostaddr != NULL && conn->pghostaddr[0] != '\0')
|
if (conn->pghostaddr != NULL && conn->pghostaddr[0] != '\0')
|
||||||
{
|
{
|
||||||
#ifdef HAVE_IPV6
|
/* Using pghostaddr avoids a hostname lookup */
|
||||||
node = conn->pghostaddr;
|
node = conn->pghostaddr;
|
||||||
hint.ai_family = AF_UNSPEC;
|
hint.ai_family = AF_UNSPEC;
|
||||||
#else
|
hint.ai_flags = AI_NUMERICHOST;
|
||||||
/* Using pghostaddr avoids a hostname lookup */
|
|
||||||
struct in_addr addr;
|
|
||||||
|
|
||||||
if (!inet_aton(conn->pghostaddr, &addr))
|
|
||||||
{
|
|
||||||
printfPQExpBuffer(&conn->errorMessage,
|
|
||||||
libpq_gettext("invalid host address: %s\n"),
|
|
||||||
conn->pghostaddr);
|
|
||||||
goto connect_errReturn;
|
|
||||||
}
|
|
||||||
|
|
||||||
family = AF_INET;
|
|
||||||
|
|
||||||
memcpy((char *) &(conn->raddr.in.sin_addr),
|
|
||||||
(char *) &addr, sizeof(addr));
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
else if (conn->pghost != NULL && conn->pghost[0] != '\0')
|
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;
|
node = conn->pghost;
|
||||||
hint.ai_family = AF_UNSPEC;
|
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
|
else
|
||||||
{
|
{
|
||||||
|
/* pghostaddr and pghost are NULL, so use Unix domain socket */
|
||||||
#ifdef HAVE_UNIX_SOCKETS
|
#ifdef HAVE_UNIX_SOCKETS
|
||||||
#ifdef HAVE_IPV6
|
|
||||||
node = unix_node;
|
node = unix_node;
|
||||||
hint.ai_family = AF_UNIX;
|
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);
|
UNIXSOCK_PATH(conn->raddr.un, portnum, conn->pgunixsocket);
|
||||||
conn->raddr_len = UNIXSOCK_LEN(conn->raddr.un);
|
conn->raddr_len = UNIXSOCK_LEN(conn->raddr.un);
|
||||||
StrNCpy(portstr, conn->raddr.un.sun_path, sizeof(portstr));
|
StrNCpy(portstr, conn->raddr.un.sun_path, sizeof(portstr));
|
||||||
@ -931,7 +865,6 @@ connectDBStart(PGconn *conn)
|
|||||||
#endif /* HAVE_UNIX_SOCKETS */
|
#endif /* HAVE_UNIX_SOCKETS */
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_IPV6
|
|
||||||
/* Use getaddrinfo2() to resolve the address */
|
/* Use getaddrinfo2() to resolve the address */
|
||||||
ret = getaddrinfo2(node, portstr, &hint, &addrs);
|
ret = getaddrinfo2(node, portstr, &hint, &addrs);
|
||||||
if (ret || addrs == NULL)
|
if (ret || addrs == NULL)
|
||||||
@ -941,40 +874,27 @@ connectDBStart(PGconn *conn)
|
|||||||
gai_strerror(ret));
|
gai_strerror(ret));
|
||||||
goto connect_errReturn;
|
goto connect_errReturn;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* For IPV6 we loop over the possible addresses returned by
|
* We loop over the possible addresses returned by getaddrinfo2(),
|
||||||
* getaddrinfo2(), and fail only when they all fail (reporting the
|
* and fail only when they all fail (reporting the error returned
|
||||||
* error returned for the *last* alternative, which may not be what
|
* for the *last* alternative, which may not be what users expect
|
||||||
* users expect :-(). Otherwise, there is no true loop here.
|
* :-().
|
||||||
*
|
*
|
||||||
* In either case, we never actually fall out of the loop; the
|
* In either case, we never actually fall out of the loop; the
|
||||||
* only exits are via "break" or "goto connect_errReturn". Thus,
|
* only exits are via "break" or "goto connect_errReturn". Thus,
|
||||||
* there is no exit test in the for().
|
* there is no exit test in the for().
|
||||||
*/
|
*/
|
||||||
for (
|
for (addr_cur = addrs; ; addr_cur = addr_cur->ai_next)
|
||||||
#ifdef HAVE_IPV6
|
|
||||||
addr_cur = addrs; ; addr_cur = addr_cur->ai_next
|
|
||||||
#else
|
|
||||||
;;
|
|
||||||
#endif
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
/* Open a socket */
|
/* Open a socket */
|
||||||
#ifdef HAVE_IPV6
|
|
||||||
conn->sock = socket(addr_cur->ai_family, SOCK_STREAM,
|
conn->sock = socket(addr_cur->ai_family, SOCK_STREAM,
|
||||||
addr_cur->ai_protocol);
|
addr_cur->ai_protocol);
|
||||||
#else
|
|
||||||
conn->sock = socket(family, SOCK_STREAM, 0);
|
|
||||||
#endif
|
|
||||||
if (conn->sock < 0)
|
if (conn->sock < 0)
|
||||||
{
|
{
|
||||||
#ifdef HAVE_IPV6
|
|
||||||
/* ignore socket() failure if we have more addrs to try */
|
/* ignore socket() failure if we have more addrs to try */
|
||||||
if (addr_cur->ai_next != NULL)
|
if (addr_cur->ai_next != NULL)
|
||||||
continue;
|
continue;
|
||||||
#endif
|
|
||||||
printfPQExpBuffer(&conn->errorMessage,
|
printfPQExpBuffer(&conn->errorMessage,
|
||||||
libpq_gettext("could not create socket: %s\n"),
|
libpq_gettext("could not create socket: %s\n"),
|
||||||
SOCK_STRERROR(SOCK_ERRNO));
|
SOCK_STRERROR(SOCK_ERRNO));
|
||||||
@ -987,11 +907,7 @@ connectDBStart(PGconn *conn)
|
|||||||
* using SSL, then we need the blocking I/O (XXX Can this be fixed?).
|
* using SSL, then we need the blocking I/O (XXX Can this be fixed?).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef HAVE_IPV6
|
|
||||||
if (isAF_INETx(addr_cur->ai_family))
|
if (isAF_INETx(addr_cur->ai_family))
|
||||||
#else
|
|
||||||
if (isAF_INETx(family))
|
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
if (!connectNoDelay(conn))
|
if (!connectNoDelay(conn))
|
||||||
goto connect_errReturn;
|
goto connect_errReturn;
|
||||||
@ -1012,11 +928,7 @@ connectDBStart(PGconn *conn)
|
|||||||
* ----------
|
* ----------
|
||||||
*/
|
*/
|
||||||
retry1:
|
retry1:
|
||||||
#ifdef HAVE_IPV6
|
|
||||||
if (connect(conn->sock, addr_cur->ai_addr, addr_cur->ai_addrlen) < 0)
|
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)
|
if (SOCK_ERRNO == EINTR)
|
||||||
/* Interrupted system call - we'll just try again */
|
/* Interrupted system call - we'll just try again */
|
||||||
@ -1043,7 +955,6 @@ retry1:
|
|||||||
* This connection failed. We need to close the socket,
|
* This connection failed. We need to close the socket,
|
||||||
* and either loop to try the next address or report an error.
|
* 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 */
|
/* ignore connect() failure if we have more addrs to try */
|
||||||
if (addr_cur->ai_next != NULL)
|
if (addr_cur->ai_next != NULL)
|
||||||
{
|
{
|
||||||
@ -1051,19 +962,19 @@ retry1:
|
|||||||
conn->sock = -1;
|
conn->sock = -1;
|
||||||
continue;
|
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);
|
connectFailureMessage(conn, SOCK_ERRNO);
|
||||||
goto connect_errReturn;
|
goto connect_errReturn;
|
||||||
} /* loop over addrs */
|
} /* loop over addrs */
|
||||||
|
|
||||||
#ifdef HAVE_IPV6
|
|
||||||
/* Remember the successfully opened address alternative */
|
/* Remember the successfully opened address alternative */
|
||||||
memcpy(&conn->raddr, addr_cur->ai_addr, addr_cur->ai_addrlen);
|
memcpy(&conn->raddr, addr_cur->ai_addr, addr_cur->ai_addrlen);
|
||||||
conn->raddr_len = addr_cur->ai_addrlen;
|
conn->raddr_len = addr_cur->ai_addrlen;
|
||||||
/* and release the address list */
|
/* and release the address list */
|
||||||
FREEADDRINFO2(hint.ai_family, addrs);
|
freeaddrinfo2(hint.ai_family, addrs);
|
||||||
addrs = NULL;
|
addrs = NULL;
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef USE_SSL
|
#ifdef USE_SSL
|
||||||
/* Attempt to negotiate SSL usage */
|
/* Attempt to negotiate SSL usage */
|
||||||
@ -1153,10 +1064,8 @@ connect_errReturn:
|
|||||||
conn->sock = -1;
|
conn->sock = -1;
|
||||||
}
|
}
|
||||||
conn->status = CONNECTION_BAD;
|
conn->status = CONNECTION_BAD;
|
||||||
#ifdef HAVE_IPV6
|
|
||||||
if (addrs != NULL)
|
if (addrs != NULL)
|
||||||
FREEADDRINFO2(hint.ai_family, addrs);
|
freeaddrinfo2(hint.ai_family, addrs);
|
||||||
#endif
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
132
src/port/getaddrinfo.c
Normal file
132
src/port/getaddrinfo.c
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
/* $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);
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user