Обсуждение: Proposed patch to getaddrinfo.c to support IPv6 on Windows
I’m proposing this change to /src/port/getaddrinfo.c to support IPv6 under windows.
10a11,14
> * Windows may or may not have these routines, so we handle Windows special
> * by dynamically checking for their existence. If they already exist, we
> * use the Windows native routines, but if not, we use our own.
> *
31a36,121
>
> #ifdef WIN32
>
> #define WIN32_LEAN_AND_MEAN
> /* Bring in windows.h for LoadLibrary, FreeLibrary, and GetProcAddress routines */
> #include <windows.h>
>
> /*
> * 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 * host, int hostlen, char * serv, int servlen, int flags);
>
> /* static pointers to the native Windows IPv6 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 Windows 2003 (and longhorn/vista), the IPv6
> * routines are present the WinSock 2 library (ws2_32.dll). Try that first
> */
>
> hLibrary = LoadLibraryA("ws2_32");
>
> if (hLibrary == NULL || GetProcAddress(hLibrary, "getaddrinfo") == NULL)
> {
> /* Well, ws2_32 doesn't exist, or more likely doesn't have getaddrinfo. */
> if (hLibrary != NULL)
> FreeLibrary(hLibrary);
>
> /* In Windows 2000, there was only the IPv6 Technology Preview
> * look in the IPv6 WinSock library (wship6.dll).
> */
>
> hLibrary = LoadLibraryA("wship6");
> }
>
> /* If hLibrary is null, we couldn't find a dll that supports the functions */
> if (hLibrary != NULL)
> {
> /* We found a dll, so now get the addresses of the routines */
>
> getaddrinfo_ptr = GetProcAddress(hLibrary, "getaddrinfo");
> freeaddrinfo_ptr = GetProcAddress(hLibrary, "freeaddrinfo");
> getnameinfo_ptr = 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
>
>
49a140,148
> #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
>
162a262,272
> #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)(node,service,hintp,res);
> return;
> }
> #endif
218a329,338
>
> #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
>
Вложения
Context diff, please, diff -c.
---------------------------------------------------------------------------
Chuck McDevitt wrote:
> I'm proposing this change to /src/port/getaddrinfo.c to support IPv6
> under windows.
>
>
>
> 10a11,14
>
> > * Windows may or may not have these routines, so we handle Windows
> special
>
> > * by dynamically checking for their existence. If they already
> exist, we
>
> > * use the Windows native routines, but if not, we use our own.
>
> > *
>
> 31a36,121
>
> >
>
> > #ifdef WIN32
>
> >
>
> > #define WIN32_LEAN_AND_MEAN
>
> > /* Bring in windows.h for LoadLibrary, FreeLibrary, and GetProcAddress
> routines */
>
> > #include <windows.h>
>
> >
>
> > /*
>
> > * 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 * host, int hostlen, char * serv, int servlen, int flags);
>
> >
>
> > /* static pointers to the native Windows IPv6 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 Windows 2003 (and longhorn/vista), the IPv6
>
> > * routines are present the WinSock 2 library (ws2_32.dll). Try
> that first
>
> > */
>
> >
>
> > hLibrary = LoadLibraryA("ws2_32");
>
> >
>
> > if (hLibrary == NULL || GetProcAddress(hLibrary, "getaddrinfo") ==
> NULL)
>
> > {
>
> > /* Well, ws2_32 doesn't exist, or more likely doesn't have
> getaddrinfo. */
>
> > if (hLibrary != NULL)
>
> > FreeLibrary(hLibrary);
>
> >
>
> > /* In Windows 2000, there was only the IPv6 Technology
> Preview
>
> > * look in the IPv6 WinSock library (wship6.dll).
>
> > */
>
> >
>
> > hLibrary = LoadLibraryA("wship6");
>
> > }
>
> >
>
> > /* If hLibrary is null, we couldn't find a dll that supports the
> functions */
>
> > if (hLibrary != NULL)
>
> > {
>
> > /* We found a dll, so now get the addresses of the routines
> */
>
> >
>
> > getaddrinfo_ptr = GetProcAddress(hLibrary, "getaddrinfo");
>
> > freeaddrinfo_ptr = GetProcAddress(hLibrary, "freeaddrinfo");
>
> > getnameinfo_ptr = 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
>
> >
>
> >
>
> 49a140,148
>
> > #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
>
> >
>
> 162a262,272
>
> > #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)(node,service,hintp,res);
>
> > return;
>
> > }
>
> > #endif
>
> 218a329,338
>
> >
>
> > #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
>
> >
>
Content-Description: getaddrinfo.patch
[ Attachment, skipping... ]
>
> ---------------------------(end of broadcast)---------------------------
> TIP 1: if posting/reading through Usenet, please send an appropriate
> subscribe-nomail command to majordomo@postgresql.org so that your
> message can get through to the mailing list cleanly
--
Bruce Momjian | http://candle.pha.pa.us
pgman@candle.pha.pa.us | (610) 359-1001
+ If your life is a hard drive, | 13 Roberts Road
+ Christ can be your backup. | Newtown Square, Pennsylvania 19073
Bruce Momjian wrote:
>Context diff, please, diff -c.
>
>
>
>
It needed dos2unix and pgindent as well. Here's a cleaned patch.
Thanks to Chuck for doing this work.
cheers
andrew
*** src/port/getaddrinfo.c 2005-07-28 00:03:14.000000000 -0400
--- /home/andrew/getaddrinfo.c 2005-08-24 16:04:29.000000000 -0400
***************
*** 8,13 ****
--- 8,17 ----
* 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 special
+ * by dynamically checking for their existance. If they already exist, we
+ * use the Windows native routines, but if not, we use our own.
+ *
*
* Copyright (c) 2003-2005, PostgreSQL Global Development Group
*
***************
*** 29,34 ****
--- 33,132 ----
#include "getaddrinfo.h"
+
+ #ifdef WIN32
+
+ #define WIN32_LEAN_AND_MEAN
+ /* Bring in windows.h for LoadLibrary, FreeLibrary, and GetProcAddress routines */
+ #include <windows.h>
+
+ /*
+ * 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 *host, int hostlen, char *serv, int servlen, int flags);
+
+ /* static pointers to the native Windows IPv6 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 Windows 2003 (and longhorn/vista), the IPv6
+ * routines are present the WinSock 2 library (ws2_32.dll). Try that first
+ */
+
+ hLibrary = LoadLibraryA("ws2_32");
+
+ if (hLibrary == NULL || GetProcAddress(hLibrary, "getaddrinfo") == NULL)
+ {
+ /*
+ * Well, ws2_32 doesn't exist, or more likely doesn't have
+ * getaddrinfo.
+ */
+ if (hLibrary != NULL)
+ FreeLibrary(hLibrary);
+
+ /*
+ * In Windows 2000, there was only the IPv6 Technology Preview look in
+ * the IPv6 WinSock library (wship6.dll).
+ */
+
+ hLibrary = LoadLibraryA("wship6");
+ }
+
+ /* If hLibrary is null, we couldn't find a dll that supports the functions */
+ if (hLibrary != NULL)
+ {
+ /* We found a dll, so now get the addresses of the routines */
+
+ getaddrinfo_ptr = GetProcAddress(hLibrary, "getaddrinfo");
+ freeaddrinfo_ptr = GetProcAddress(hLibrary, "freeaddrinfo");
+ getnameinfo_ptr = 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.
*
***************
*** 47,52 ****
--- 145,159 ----
*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));
***************
*** 160,165 ****
--- 267,283 ----
{
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) (node, service, hintp, res);
+ return;
+ }
+ #endif
if (res->ai_addr)
free(res->ai_addr);
free(res);
***************
*** 188,194 ****
}
return hstrerror(hcode);
-
#else /* !HAVE_HSTRERROR */
switch (errcode)
--- 306,311 ----
***************
*** 216,221 ****
--- 333,348 ----
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;
Andrew Dunstan <andrew@dunslane.net> writes:
>> Context diff, please, diff -c.
> It needed dos2unix and pgindent as well. Here's a cleaned patch.
> Thanks to Chuck for doing this work.
Applied, thanks.
regards, tom lane