Thread: Proposed patch to getaddrinfo.c to support IPv6 on Windows

Proposed patch to getaddrinfo.c to support IPv6 on Windows

From
"Chuck McDevitt"
Date:

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

Attachment

Re: Proposed patch to getaddrinfo.c to support IPv6 on Windows

From
Bruce Momjian
Date:
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

Re: [HACKERS] Proposed patch to getaddrinfo.c to support

From
Andrew Dunstan
Date:

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;

Re: [HACKERS] Proposed patch to getaddrinfo.c to support

From
Tom Lane
Date:
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