Обсуждение: 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