mirror of https://github.com/postgres/postgres
Remove replacement code for getaddrinfo.
SUSv3, all targeted Unixes and modern Windows have getaddrinfo() and related interfaces. Drop the replacement implementation, and adjust some headers slightly to make sure that the APIs are visible everywhere using standard POSIX headers and names. Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us> Discussion: https://postgr.es/m/CA%2BhUKG%2BL_3brvh%3D8e0BW_VfX9h7MtwgN%3DnFHP5o7X2oZucY9dg%40mail.gmail.com
This commit is contained in:
parent
de42bc3ac8
commit
5579388d2d
|
@ -89,17 +89,6 @@ AC_DEFUN([PGAC_STRUCT_SOCKADDR_STORAGE_MEMBERS],
|
|||
])])# PGAC_STRUCT_SOCKADDR_STORAGE_MEMBERS
|
||||
|
||||
|
||||
# PGAC_STRUCT_ADDRINFO
|
||||
# -----------------------
|
||||
# If `struct addrinfo' exists, define HAVE_STRUCT_ADDRINFO.
|
||||
AC_DEFUN([PGAC_STRUCT_ADDRINFO],
|
||||
[AC_CHECK_TYPES([struct addrinfo], [], [],
|
||||
[#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netdb.h>
|
||||
])])# PGAC_STRUCT_ADDRINFO
|
||||
|
||||
|
||||
# PGAC_TYPE_LOCALE_T
|
||||
# ------------------
|
||||
# Check for the locale_t type and find the right header file. macOS
|
||||
|
|
|
@ -15119,20 +15119,6 @@ cat >>confdefs.h <<_ACEOF
|
|||
_ACEOF
|
||||
|
||||
|
||||
fi
|
||||
|
||||
ac_fn_c_check_type "$LINENO" "struct addrinfo" "ac_cv_type_struct_addrinfo" "#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netdb.h>
|
||||
|
||||
"
|
||||
if test "x$ac_cv_type_struct_addrinfo" = xyes; then :
|
||||
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define HAVE_STRUCT_ADDRINFO 1
|
||||
_ACEOF
|
||||
|
||||
|
||||
fi
|
||||
|
||||
|
||||
|
@ -16533,34 +16519,6 @@ esac
|
|||
$as_echo "$as_me: On $host_os we will use our strtof wrapper." >&6;}
|
||||
fi
|
||||
|
||||
# System's version of getaddrinfo(), if any, may be used only if we found
|
||||
# a definition for struct addrinfo; see notes in src/include/getaddrinfo.h.
|
||||
# We use only our own getaddrinfo.c on Windows, but it's time to revisit that.
|
||||
if test x"$ac_cv_type_struct_addrinfo" = xyes && \
|
||||
test "$PORTNAME" != "win32"; then
|
||||
ac_fn_c_check_func "$LINENO" "getaddrinfo" "ac_cv_func_getaddrinfo"
|
||||
if test "x$ac_cv_func_getaddrinfo" = xyes; then :
|
||||
$as_echo "#define HAVE_GETADDRINFO 1" >>confdefs.h
|
||||
|
||||
else
|
||||
case " $LIBOBJS " in
|
||||
*" getaddrinfo.$ac_objext "* ) ;;
|
||||
*) LIBOBJS="$LIBOBJS getaddrinfo.$ac_objext"
|
||||
;;
|
||||
esac
|
||||
|
||||
fi
|
||||
|
||||
|
||||
else
|
||||
case " $LIBOBJS " in
|
||||
*" getaddrinfo.$ac_objext "* ) ;;
|
||||
*) LIBOBJS="$LIBOBJS getaddrinfo.$ac_objext"
|
||||
;;
|
||||
esac
|
||||
|
||||
fi
|
||||
|
||||
# Similarly, use system's getopt_long() only if system provides struct option.
|
||||
if test x"$ac_cv_type_struct_option" = xyes ; then
|
||||
ac_fn_c_check_func "$LINENO" "getopt_long" "ac_cv_func_getopt_long"
|
||||
|
|
11
configure.ac
11
configure.ac
|
@ -1619,7 +1619,6 @@ PGAC_STRUCT_TIMEZONE
|
|||
PGAC_UNION_SEMUN
|
||||
AC_CHECK_TYPES(socklen_t, [], [], [#include <sys/socket.h>])
|
||||
PGAC_STRUCT_SOCKADDR_STORAGE_MEMBERS
|
||||
PGAC_STRUCT_ADDRINFO
|
||||
|
||||
PGAC_TYPE_LOCALE_T
|
||||
|
||||
|
@ -1849,16 +1848,6 @@ if test "$PORTNAME" = "win32" -o "$PORTNAME" = "cygwin"; then
|
|||
AC_MSG_NOTICE([On $host_os we will use our strtof wrapper.])
|
||||
fi
|
||||
|
||||
# System's version of getaddrinfo(), if any, may be used only if we found
|
||||
# a definition for struct addrinfo; see notes in src/include/getaddrinfo.h.
|
||||
# We use only our own getaddrinfo.c on Windows, but it's time to revisit that.
|
||||
if test x"$ac_cv_type_struct_addrinfo" = xyes && \
|
||||
test "$PORTNAME" != "win32"; then
|
||||
AC_REPLACE_FUNCS([getaddrinfo])
|
||||
else
|
||||
AC_LIBOBJ(getaddrinfo)
|
||||
fi
|
||||
|
||||
# Similarly, use system's getopt_long() only if system provides struct option.
|
||||
if test x"$ac_cv_type_struct_option" = xyes ; then
|
||||
AC_REPLACE_FUNCS([getopt_long])
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include <sys/select.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netdb.h>
|
||||
#include <pwd.h>
|
||||
#include <unistd.h>
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include <fcntl.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netdb.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <unistd.h>
|
||||
|
|
|
@ -50,6 +50,8 @@
|
|||
|
||||
#include <dirent.h>
|
||||
#include <fcntl.h>
|
||||
#include <netdb.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
|
@ -72,7 +74,6 @@
|
|||
#include "common/string.h"
|
||||
#include "common/username.h"
|
||||
#include "fe_utils/string_utils.h"
|
||||
#include "getaddrinfo.h"
|
||||
#include "getopt_long.h"
|
||||
#include "mb/pg_wchar.h"
|
||||
#include "miscadmin.h"
|
||||
|
|
|
@ -14,7 +14,9 @@
|
|||
#ifndef IP_H
|
||||
#define IP_H
|
||||
|
||||
#include "getaddrinfo.h" /* pgrminclude ignore */
|
||||
#include <netdb.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include "libpq/pqcomm.h" /* pgrminclude ignore */
|
||||
|
||||
|
||||
|
|
|
@ -1,162 +0,0 @@
|
|||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* 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
|
||||
* may provide getaddrinfo(), yet the system headers may not provide the
|
||||
* struct definitions needed to call it. To avoid conflict with the libbind
|
||||
* definition in such cases, we rename our routines to pg_xxx() via macros.
|
||||
*
|
||||
* This code will also work on platforms where struct addrinfo is defined
|
||||
* in the system headers but no getaddrinfo() can be located.
|
||||
*
|
||||
* Copyright (c) 2003-2022, PostgreSQL Global Development Group
|
||||
*
|
||||
* src/include/getaddrinfo.h
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
#ifndef GETADDRINFO_H
|
||||
#define GETADDRINFO_H
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <netdb.h>
|
||||
|
||||
|
||||
/* Various macros that ought to be in <netdb.h>, but might not be */
|
||||
|
||||
#ifndef EAI_FAIL
|
||||
#ifndef WIN32
|
||||
#define EAI_BADFLAGS (-1)
|
||||
#define EAI_NONAME (-2)
|
||||
#define EAI_AGAIN (-3)
|
||||
#define EAI_FAIL (-4)
|
||||
#define EAI_FAMILY (-6)
|
||||
#define EAI_SOCKTYPE (-7)
|
||||
#define EAI_SERVICE (-8)
|
||||
#define EAI_MEMORY (-10)
|
||||
#define EAI_SYSTEM (-11)
|
||||
#else /* WIN32 */
|
||||
#ifdef _MSC_VER
|
||||
#ifndef WSA_NOT_ENOUGH_MEMORY
|
||||
#define WSA_NOT_ENOUGH_MEMORY (WSAENOBUFS)
|
||||
#endif
|
||||
#define WSATYPE_NOT_FOUND (WSABASEERR+109)
|
||||
#endif
|
||||
#define EAI_AGAIN WSATRY_AGAIN
|
||||
#define EAI_BADFLAGS WSAEINVAL
|
||||
#define EAI_FAIL WSANO_RECOVERY
|
||||
#define EAI_FAMILY WSAEAFNOSUPPORT
|
||||
#define EAI_MEMORY WSA_NOT_ENOUGH_MEMORY
|
||||
#define EAI_NODATA WSANO_DATA
|
||||
#define EAI_NONAME WSAHOST_NOT_FOUND
|
||||
#define EAI_SERVICE WSATYPE_NOT_FOUND
|
||||
#define EAI_SOCKTYPE WSAESOCKTNOSUPPORT
|
||||
#endif /* !WIN32 */
|
||||
#endif /* !EAI_FAIL */
|
||||
|
||||
#ifndef AI_PASSIVE
|
||||
#define AI_PASSIVE 0x0001
|
||||
#endif
|
||||
|
||||
#ifndef AI_NUMERICHOST
|
||||
/*
|
||||
* some platforms don't support AI_NUMERICHOST; define as zero if using
|
||||
* the system version of getaddrinfo...
|
||||
*/
|
||||
#if defined(HAVE_STRUCT_ADDRINFO) && defined(HAVE_GETADDRINFO)
|
||||
#define AI_NUMERICHOST 0
|
||||
#else
|
||||
#define AI_NUMERICHOST 0x0004
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef NI_NUMERICHOST
|
||||
#define NI_NUMERICHOST 1
|
||||
#endif
|
||||
#ifndef NI_NUMERICSERV
|
||||
#define NI_NUMERICSERV 2
|
||||
#endif
|
||||
#ifndef NI_NAMEREQD
|
||||
#define NI_NAMEREQD 4
|
||||
#endif
|
||||
|
||||
#ifndef NI_MAXHOST
|
||||
#define NI_MAXHOST 1025
|
||||
#endif
|
||||
#ifndef NI_MAXSERV
|
||||
#define NI_MAXSERV 32
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef HAVE_STRUCT_ADDRINFO
|
||||
|
||||
#ifndef WIN32
|
||||
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;
|
||||
};
|
||||
#else
|
||||
/*
|
||||
* The order of the structure elements on Win32 doesn't match the
|
||||
* order specified in the standard, but we have to match it for
|
||||
* IPv6 to work.
|
||||
*/
|
||||
struct addrinfo
|
||||
{
|
||||
int ai_flags;
|
||||
int ai_family;
|
||||
int ai_socktype;
|
||||
int ai_protocol;
|
||||
size_t ai_addrlen;
|
||||
char *ai_canonname;
|
||||
struct sockaddr *ai_addr;
|
||||
struct addrinfo *ai_next;
|
||||
};
|
||||
#endif
|
||||
#endif /* HAVE_STRUCT_ADDRINFO */
|
||||
|
||||
|
||||
#ifndef HAVE_GETADDRINFO
|
||||
|
||||
/* Rename private copies per comments above */
|
||||
#ifdef getaddrinfo
|
||||
#undef getaddrinfo
|
||||
#endif
|
||||
#define getaddrinfo pg_getaddrinfo
|
||||
|
||||
#ifdef freeaddrinfo
|
||||
#undef freeaddrinfo
|
||||
#endif
|
||||
#define freeaddrinfo pg_freeaddrinfo
|
||||
|
||||
#ifdef gai_strerror
|
||||
#undef gai_strerror
|
||||
#endif
|
||||
#define gai_strerror pg_gai_strerror
|
||||
|
||||
#ifdef getnameinfo
|
||||
#undef getnameinfo
|
||||
#endif
|
||||
#define getnameinfo pg_getnameinfo
|
||||
|
||||
extern int getaddrinfo(const char *node, const char *service,
|
||||
const struct addrinfo *hints, struct addrinfo **res);
|
||||
extern void freeaddrinfo(struct addrinfo *res);
|
||||
extern const char *gai_strerror(int errcode);
|
||||
extern int getnameinfo(const struct sockaddr *sa, int salen,
|
||||
char *node, int nodelen,
|
||||
char *service, int servicelen, int flags);
|
||||
#endif /* HAVE_GETADDRINFO */
|
||||
|
||||
#endif /* GETADDRINFO_H */
|
|
@ -33,14 +33,6 @@
|
|||
#else
|
||||
#include <gssapi/gssapi.h>
|
||||
#endif /* HAVE_GSSAPI_H */
|
||||
/*
|
||||
* GSSAPI brings in headers that set a lot of things in the global namespace on win32,
|
||||
* that doesn't match the msvc build. It gives a bunch of compiler warnings that we ignore,
|
||||
* but also defines a symbol that simply does not exist. Undefine it again.
|
||||
*/
|
||||
#ifdef _MSC_VER
|
||||
#undef HAVE_GETADDRINFO
|
||||
#endif
|
||||
#endif /* ENABLE_GSS */
|
||||
|
||||
#ifdef ENABLE_SSPI
|
||||
|
|
|
@ -178,9 +178,6 @@
|
|||
*/
|
||||
#undef HAVE_GCC__SYNC_INT64_CAS
|
||||
|
||||
/* Define to 1 if you have the `getaddrinfo' function. */
|
||||
#undef HAVE_GETADDRINFO
|
||||
|
||||
/* Define to 1 if you have the `gethostbyname_r' function. */
|
||||
#undef HAVE_GETHOSTBYNAME_R
|
||||
|
||||
|
@ -448,9 +445,6 @@
|
|||
/* Define to 1 if you have the `strsignal' function. */
|
||||
#undef HAVE_STRSIGNAL
|
||||
|
||||
/* Define to 1 if the system has the type `struct addrinfo'. */
|
||||
#undef HAVE_STRUCT_ADDRINFO
|
||||
|
||||
/* Define to 1 if the system has the type `struct cmsgcred'. */
|
||||
#undef HAVE_STRUCT_CMSGCRED
|
||||
|
||||
|
|
|
@ -1 +1,9 @@
|
|||
/* src/include/port/win32/netdb.h */
|
||||
#ifndef WIN32_NETDB_H
|
||||
#define WIN32_NETDB_H
|
||||
|
||||
#include <ws2tcpip.h>
|
||||
|
||||
#define gai_strerror gai_strerrorA
|
||||
|
||||
#endif
|
||||
|
|
|
@ -12,9 +12,11 @@
|
|||
#ifndef _WALRECEIVER_H
|
||||
#define _WALRECEIVER_H
|
||||
|
||||
#include <netdb.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include "access/xlog.h"
|
||||
#include "access/xlogdefs.h"
|
||||
#include "getaddrinfo.h" /* for NI_MAXHOST */
|
||||
#include "pgtime.h"
|
||||
#include "port/atomics.h"
|
||||
#include "replication/logicalproto.h"
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <ctype.h>
|
||||
#include <netdb.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
|
|
|
@ -23,6 +23,8 @@
|
|||
/* We assume libpq-fe.h has already been included. */
|
||||
#include "libpq-events.h"
|
||||
|
||||
#include <netdb.h>
|
||||
#include <sys/socket.h>
|
||||
#include <time.h>
|
||||
#ifndef WIN32
|
||||
#include <sys/time.h>
|
||||
|
@ -38,7 +40,6 @@
|
|||
#endif
|
||||
|
||||
/* include stuff common to fe and be */
|
||||
#include "getaddrinfo.h"
|
||||
#include "libpq/pqcomm.h"
|
||||
/* include stuff found in fe only */
|
||||
#include "fe-auth-sasl.h"
|
||||
|
|
|
@ -84,10 +84,6 @@ libpgport.a: $(OBJS)
|
|||
rm -f $@
|
||||
$(AR) $(AROPT) $@ $^
|
||||
|
||||
# getaddrinfo.o and getaddrinfo_shlib.o need PTHREAD_CFLAGS (but getaddrinfo_srv.o does not)
|
||||
getaddrinfo.o: CFLAGS+=$(PTHREAD_CFLAGS)
|
||||
getaddrinfo_shlib.o: CFLAGS+=$(PTHREAD_CFLAGS)
|
||||
|
||||
# thread.o and thread_shlib.o need PTHREAD_CFLAGS (but thread_srv.o does not)
|
||||
thread.o: CFLAGS+=$(PTHREAD_CFLAGS)
|
||||
thread_shlib.o: CFLAGS+=$(PTHREAD_CFLAGS)
|
||||
|
|
|
@ -1,439 +0,0 @@
|
|||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* 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().
|
||||
*
|
||||
* Windows may or may not have these routines, so we handle Windows specially
|
||||
* by dynamically checking for their existence. If they already exist, we
|
||||
* use the Windows native routines, but if not, we use our own.
|
||||
*
|
||||
*
|
||||
* Copyright (c) 2003-2022, PostgreSQL Global Development Group
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* src/port/getaddrinfo.c
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/* This is intended to be used in both frontend and backend, so use c.h */
|
||||
#include "c.h"
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <netdb.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include "getaddrinfo.h"
|
||||
#include "libpq/pqcomm.h" /* needed for struct sockaddr_storage */
|
||||
#include "port/pg_bswap.h"
|
||||
|
||||
|
||||
#ifdef FRONTEND
|
||||
static int pqGethostbyname(const char *name,
|
||||
struct hostent *resultbuf,
|
||||
char *buffer, size_t buflen,
|
||||
struct hostent **result,
|
||||
int *herrno);
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
/*
|
||||
* The native routines may or may not exist on the Windows platform we are on,
|
||||
* so we dynamically look up the routines, and call them via function pointers.
|
||||
* Here we need to declare what the function pointers look like
|
||||
*/
|
||||
typedef int (__stdcall * getaddrinfo_ptr_t) (const char *nodename,
|
||||
const char *servname,
|
||||
const struct addrinfo *hints,
|
||||
struct addrinfo **res);
|
||||
|
||||
typedef void (__stdcall * freeaddrinfo_ptr_t) (struct addrinfo *ai);
|
||||
|
||||
typedef int (__stdcall * getnameinfo_ptr_t) (const struct sockaddr *sa,
|
||||
int salen,
|
||||
char *node, int nodelen,
|
||||
char *service, int servicelen,
|
||||
int flags);
|
||||
|
||||
/* static pointers to the native routines, so we only do the lookup once. */
|
||||
static getaddrinfo_ptr_t getaddrinfo_ptr = NULL;
|
||||
static freeaddrinfo_ptr_t freeaddrinfo_ptr = NULL;
|
||||
static getnameinfo_ptr_t getnameinfo_ptr = NULL;
|
||||
|
||||
|
||||
static bool
|
||||
haveNativeWindowsIPv6routines(void)
|
||||
{
|
||||
void *hLibrary = NULL;
|
||||
static bool alreadyLookedForIpv6routines = false;
|
||||
|
||||
if (alreadyLookedForIpv6routines)
|
||||
return (getaddrinfo_ptr != NULL);
|
||||
|
||||
/*
|
||||
* For Windows XP and later versions, the IPv6 routines are present in the
|
||||
* WinSock 2 library (ws2_32.dll).
|
||||
*/
|
||||
hLibrary = LoadLibraryA("ws2_32");
|
||||
|
||||
/* If hLibrary is null, we couldn't find a dll with functions */
|
||||
if (hLibrary != NULL)
|
||||
{
|
||||
/* We found a dll, so now get the addresses of the routines */
|
||||
|
||||
getaddrinfo_ptr = (getaddrinfo_ptr_t) (pg_funcptr_t) GetProcAddress(hLibrary,
|
||||
"getaddrinfo");
|
||||
freeaddrinfo_ptr = (freeaddrinfo_ptr_t) (pg_funcptr_t) GetProcAddress(hLibrary,
|
||||
"freeaddrinfo");
|
||||
getnameinfo_ptr = (getnameinfo_ptr_t) (pg_funcptr_t) GetProcAddress(hLibrary,
|
||||
"getnameinfo");
|
||||
|
||||
/*
|
||||
* If any one of the routines is missing, let's play it safe and
|
||||
* ignore them all
|
||||
*/
|
||||
if (getaddrinfo_ptr == NULL ||
|
||||
freeaddrinfo_ptr == NULL ||
|
||||
getnameinfo_ptr == NULL)
|
||||
{
|
||||
FreeLibrary(hLibrary);
|
||||
hLibrary = NULL;
|
||||
getaddrinfo_ptr = NULL;
|
||||
freeaddrinfo_ptr = NULL;
|
||||
getnameinfo_ptr = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
alreadyLookedForIpv6routines = true;
|
||||
return (getaddrinfo_ptr != NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* get address info for ipv4 sockets.
|
||||
*
|
||||
* Bugs: - only one addrinfo is set even though hintp is NULL or
|
||||
* ai_socktype is 0
|
||||
* - AI_CANONNAME is not supported.
|
||||
* - servname can only be a number, not text.
|
||||
*/
|
||||
int
|
||||
getaddrinfo(const char *node, const char *service,
|
||||
const struct addrinfo *hintp,
|
||||
struct addrinfo **res)
|
||||
{
|
||||
struct addrinfo *ai;
|
||||
struct sockaddr_in sin,
|
||||
*psin;
|
||||
struct addrinfo hints;
|
||||
|
||||
#ifdef WIN32
|
||||
|
||||
/*
|
||||
* If Windows has native IPv6 support, use the native Windows routine.
|
||||
* Otherwise, fall through and use our own code.
|
||||
*/
|
||||
if (haveNativeWindowsIPv6routines())
|
||||
return (*getaddrinfo_ptr) (node, service, hintp, res);
|
||||
#endif
|
||||
|
||||
if (hintp == NULL)
|
||||
{
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_family = AF_INET;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
}
|
||||
else
|
||||
memcpy(&hints, hintp, sizeof(hints));
|
||||
|
||||
if (hints.ai_family != AF_INET && hints.ai_family != AF_UNSPEC)
|
||||
return EAI_FAMILY;
|
||||
|
||||
if (hints.ai_socktype == 0)
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
|
||||
if (!node && !service)
|
||||
return EAI_NONAME;
|
||||
|
||||
memset(&sin, 0, sizeof(sin));
|
||||
|
||||
sin.sin_family = AF_INET;
|
||||
|
||||
if (node)
|
||||
{
|
||||
if (node[0] == '\0')
|
||||
sin.sin_addr.s_addr = pg_hton32(INADDR_ANY);
|
||||
else if (hints.ai_flags & AI_NUMERICHOST)
|
||||
{
|
||||
if (!inet_aton(node, &sin.sin_addr))
|
||||
return EAI_NONAME;
|
||||
}
|
||||
else
|
||||
{
|
||||
struct hostent *hp;
|
||||
|
||||
#ifdef FRONTEND
|
||||
struct hostent hpstr;
|
||||
char buf[BUFSIZ];
|
||||
int herrno = 0;
|
||||
|
||||
pqGethostbyname(node, &hpstr, buf, sizeof(buf),
|
||||
&hp, &herrno);
|
||||
#else
|
||||
hp = gethostbyname(node);
|
||||
#endif
|
||||
if (hp == NULL)
|
||||
{
|
||||
switch (h_errno)
|
||||
{
|
||||
case HOST_NOT_FOUND:
|
||||
case NO_DATA:
|
||||
return EAI_NONAME;
|
||||
case TRY_AGAIN:
|
||||
return EAI_AGAIN;
|
||||
case NO_RECOVERY:
|
||||
default:
|
||||
return EAI_FAIL;
|
||||
}
|
||||
}
|
||||
if (hp->h_addrtype != AF_INET)
|
||||
return EAI_FAIL;
|
||||
|
||||
memcpy(&(sin.sin_addr), hp->h_addr, hp->h_length);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (hints.ai_flags & AI_PASSIVE)
|
||||
sin.sin_addr.s_addr = pg_hton32(INADDR_ANY);
|
||||
else
|
||||
sin.sin_addr.s_addr = pg_hton32(INADDR_LOOPBACK);
|
||||
}
|
||||
|
||||
if (service)
|
||||
sin.sin_port = pg_hton16((unsigned short) atoi(service));
|
||||
|
||||
#ifdef HAVE_STRUCT_SOCKADDR_STORAGE_SS_LEN
|
||||
sin.sin_len = sizeof(sin);
|
||||
#endif
|
||||
|
||||
ai = malloc(sizeof(*ai));
|
||||
if (!ai)
|
||||
return EAI_MEMORY;
|
||||
|
||||
psin = malloc(sizeof(*psin));
|
||||
if (!psin)
|
||||
{
|
||||
free(ai);
|
||||
return EAI_MEMORY;
|
||||
}
|
||||
|
||||
memcpy(psin, &sin, sizeof(*psin));
|
||||
|
||||
ai->ai_flags = 0;
|
||||
ai->ai_family = AF_INET;
|
||||
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)
|
||||
{
|
||||
#ifdef WIN32
|
||||
|
||||
/*
|
||||
* If Windows has native IPv6 support, use the native Windows routine.
|
||||
* Otherwise, fall through and use our own code.
|
||||
*/
|
||||
if (haveNativeWindowsIPv6routines())
|
||||
{
|
||||
(*freeaddrinfo_ptr) (res);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
free(res->ai_addr);
|
||||
free(res);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const char *
|
||||
gai_strerror(int errcode)
|
||||
{
|
||||
#ifdef HAVE_HSTRERROR
|
||||
int hcode;
|
||||
|
||||
switch (errcode)
|
||||
{
|
||||
case EAI_NONAME:
|
||||
hcode = HOST_NOT_FOUND;
|
||||
break;
|
||||
case EAI_AGAIN:
|
||||
hcode = TRY_AGAIN;
|
||||
break;
|
||||
case EAI_FAIL:
|
||||
default:
|
||||
hcode = NO_RECOVERY;
|
||||
break;
|
||||
}
|
||||
|
||||
return hstrerror(hcode);
|
||||
#else /* !HAVE_HSTRERROR */
|
||||
|
||||
switch (errcode)
|
||||
{
|
||||
case EAI_NONAME:
|
||||
return "Unknown host";
|
||||
case EAI_AGAIN:
|
||||
return "Host name lookup failure";
|
||||
/* Errors below are probably WIN32 only */
|
||||
#ifdef EAI_BADFLAGS
|
||||
case EAI_BADFLAGS:
|
||||
return "Invalid argument";
|
||||
#endif
|
||||
#ifdef EAI_FAMILY
|
||||
case EAI_FAMILY:
|
||||
return "Address family not supported";
|
||||
#endif
|
||||
#ifdef EAI_MEMORY
|
||||
case EAI_MEMORY:
|
||||
return "Not enough memory";
|
||||
#endif
|
||||
#if defined(EAI_NODATA) && EAI_NODATA != EAI_NONAME /* MSVC/WIN64 duplicate */
|
||||
case EAI_NODATA:
|
||||
return "No host data of that type was found";
|
||||
#endif
|
||||
#ifdef EAI_SERVICE
|
||||
case EAI_SERVICE:
|
||||
return "Class type not found";
|
||||
#endif
|
||||
#ifdef EAI_SOCKTYPE
|
||||
case EAI_SOCKTYPE:
|
||||
return "Socket type not supported";
|
||||
#endif
|
||||
default:
|
||||
return "Unknown server error";
|
||||
}
|
||||
#endif /* HAVE_HSTRERROR */
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert an ipv4 address to a hostname.
|
||||
*
|
||||
* Bugs: - Only supports NI_NUMERICHOST and NI_NUMERICSERV behavior.
|
||||
* It will never resolve a hostname.
|
||||
* - No IPv6 support.
|
||||
*/
|
||||
int
|
||||
getnameinfo(const struct sockaddr *sa, int salen,
|
||||
char *node, int nodelen,
|
||||
char *service, int servicelen, int flags)
|
||||
{
|
||||
#ifdef WIN32
|
||||
|
||||
/*
|
||||
* If Windows has native IPv6 support, use the native Windows routine.
|
||||
* Otherwise, fall through and use our own code.
|
||||
*/
|
||||
if (haveNativeWindowsIPv6routines())
|
||||
return (*getnameinfo_ptr) (sa, salen, node, nodelen,
|
||||
service, servicelen, flags);
|
||||
#endif
|
||||
|
||||
/* Invalid arguments. */
|
||||
if (sa == NULL || (node == NULL && service == NULL))
|
||||
return EAI_FAIL;
|
||||
|
||||
#ifdef HAVE_IPV6
|
||||
if (sa->sa_family == AF_INET6)
|
||||
return EAI_FAMILY;
|
||||
#endif
|
||||
|
||||
/* Unsupported flags. */
|
||||
if (flags & NI_NAMEREQD)
|
||||
return EAI_AGAIN;
|
||||
|
||||
if (node)
|
||||
{
|
||||
if (sa->sa_family == AF_INET)
|
||||
{
|
||||
if (pg_inet_net_ntop(AF_INET,
|
||||
&((struct sockaddr_in *) sa)->sin_addr,
|
||||
sa->sa_family == AF_INET ? 32 : 128,
|
||||
node, nodelen) == NULL)
|
||||
return EAI_MEMORY;
|
||||
}
|
||||
else
|
||||
return EAI_MEMORY;
|
||||
}
|
||||
|
||||
if (service)
|
||||
{
|
||||
int ret = -1;
|
||||
|
||||
if (sa->sa_family == AF_INET)
|
||||
{
|
||||
ret = snprintf(service, servicelen, "%d",
|
||||
pg_ntoh16(((struct sockaddr_in *) sa)->sin_port));
|
||||
}
|
||||
if (ret < 0 || ret >= servicelen)
|
||||
return EAI_MEMORY;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Wrapper around gethostbyname() or gethostbyname_r() to mimic
|
||||
* POSIX gethostbyname_r() behaviour, if it is not available or required.
|
||||
*/
|
||||
#ifdef FRONTEND
|
||||
static int
|
||||
pqGethostbyname(const char *name,
|
||||
struct hostent *resultbuf,
|
||||
char *buffer, size_t buflen,
|
||||
struct hostent **result,
|
||||
int *herrno)
|
||||
{
|
||||
#if defined(ENABLE_THREAD_SAFETY) && defined(HAVE_GETHOSTBYNAME_R)
|
||||
|
||||
/*
|
||||
* broken (well early POSIX draft) gethostbyname_r() which returns 'struct
|
||||
* hostent *'
|
||||
*/
|
||||
*result = gethostbyname_r(name, resultbuf, buffer, buflen, herrno);
|
||||
return (*result == NULL) ? -1 : 0;
|
||||
#else
|
||||
|
||||
/* no gethostbyname_r(), just use gethostbyname() */
|
||||
*result = gethostbyname(name);
|
||||
|
||||
if (*result != NULL)
|
||||
*herrno = h_errno;
|
||||
|
||||
if (*result != NULL)
|
||||
return 0;
|
||||
else
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
#endif /* FRONTEND */
|
|
@ -101,7 +101,7 @@ sub mkvcbuild
|
|||
our @pgportfiles = qw(
|
||||
chklocale.c explicit_bzero.c
|
||||
getpeereid.c inet_aton.c
|
||||
getaddrinfo.c inet_net_ntop.c kill.c open.c
|
||||
inet_net_ntop.c kill.c open.c
|
||||
snprintf.c strlcat.c strlcpy.c dirmod.c noblock.c path.c
|
||||
dirent.c getopt.c getopt_long.c
|
||||
preadv.c pwritev.c pg_bitutils.c
|
||||
|
|
|
@ -256,7 +256,6 @@ sub GenerateFiles
|
|||
HAVE_GCC__SYNC_INT32_CAS => undef,
|
||||
HAVE_GCC__SYNC_INT32_TAS => undef,
|
||||
HAVE_GCC__SYNC_INT64_CAS => undef,
|
||||
HAVE_GETADDRINFO => undef,
|
||||
HAVE_GETHOSTBYNAME_R => undef,
|
||||
HAVE_GETIFADDRS => undef,
|
||||
HAVE_GETOPT => undef,
|
||||
|
@ -345,7 +344,6 @@ sub GenerateFiles
|
|||
HAVE_STRLCPY => undef,
|
||||
HAVE_STRNLEN => 1,
|
||||
HAVE_STRSIGNAL => undef,
|
||||
HAVE_STRUCT_ADDRINFO => 1,
|
||||
HAVE_STRUCT_CMSGCRED => undef,
|
||||
HAVE_STRUCT_OPTION => undef,
|
||||
HAVE_STRUCT_SOCKADDR_SA_LEN => undef,
|
||||
|
|
Loading…
Reference in New Issue