OSDN Git Service

* net.cc (cygwin_getaddrinfo): Check ai_flags for valid values.
authorcorinna <corinna>
Wed, 31 Jan 2007 15:10:18 +0000 (15:10 +0000)
committercorinna <corinna>
Wed, 31 Jan 2007 15:10:18 +0000 (15:10 +0000)
Handle AI_NUMERICSERV.  Handle AI_ADDRCONFIG behaviour on Vista.
* include/netdb.h (AI_NUMERICSERV): Add missing flag.

winsup/cygwin/ChangeLog
winsup/cygwin/include/netdb.h
winsup/cygwin/net.cc

index ba4a9ff..2b2c530 100644 (file)
@@ -1,3 +1,9 @@
+2007-01-31  Corinna Vinschen  <corinna@vinschen.de>
+
+       * net.cc (cygwin_getaddrinfo): Check ai_flags for valid values.
+       Handle AI_NUMERICSERV.  Handle AI_ADDRCONFIG behaviour on Vista.
+       * include/netdb.h (AI_NUMERICSERV): Add missing flag.
+
 2007-01-30  Corinna Vinschen  <corinna@vinschen.de>
 
        * fhandler_disk_file.cc (fhandler_disk_file::closedir): Add dir name
index 59c3286..4f2ead1 100644 (file)
@@ -147,6 +147,7 @@ extern __declspec(dllimport) int h_errno;
 #define AI_PASSIVE      1
 #define AI_CANONNAME    2
 #define AI_NUMERICHOST  4
+#define AI_NUMERICSERV  8
 /* Only available since Vista. Ignored on older systems. */
 #define AI_ALL          256
 #define AI_ADDRCONFIG   1024
index a28a414..5ece859 100644 (file)
@@ -3875,9 +3875,42 @@ cygwin_getaddrinfo (const char *hostname, const char *servname,
   myfault efault;
   if (efault.faulted (EFAULT))
     return EAI_SYSTEM;
+  /* Both subsequent getaddrinfo implementations let all possible values
+     in ai_flags slip through and just ignore unknowen values.  So we have
+     to check manually here. */
+  if (hints && (hints->ai_flags
+               & ~(AI_PASSIVE | AI_CANONNAME | AI_NUMERICHOST | AI_ALL
+                   | AI_NUMERICSERV | AI_ADDRCONFIG | AI_V4MAPPED)))
+    return EAI_BADFLAGS;
+  /* AI_NUMERICSERV is not supported in our replacement getaddrinfo, nor
+     is it supported by Winsock prior to Vista.  We just check the servname
+     parameter by ourselves here. */
+  if (hints && (hints->ai_flags & AI_NUMERICSERV))
+    {
+      char *p;
+      if (servname && *servname && (strtoul (servname, &p, 10), *p))
+       return EAI_NONAME;
+    }
   load_ipv6 ();
   if (getaddrinfo)
-    return w32_to_gai_err (getaddrinfo (hostname, servname, hints, res));
+    {
+      struct addrinfo nhints;
+
+      /* AI_ADDRCONFIG is not supported prior to Vista.  Rather it's
+        the default and only possible setting.
+        On Vista, the default behaviour is as if AI_ADDRCONFIG is set,
+        apparently for performance reasons.  To get the POSIX default
+        behaviour, the AI_ALL flag has to be set. */
+      if (wincap.has_gaa_on_link_prefix ()
+         && hints && (hints->ai_flags & AI_ADDRCONFIG)
+         && hints->ai_family == PF_UNSPEC)
+        {
+         nhints = *hints;
+         hints = &nhints;
+         nhints.ai_flags |= AI_ALL;
+       }
+      return w32_to_gai_err (getaddrinfo (hostname, servname, hints, res));
+    }
   return ipv4_getaddrinfo (hostname, servname, hints, res);
 }