From c2decfdc8a508e3fbc299c67964895ba8d593365 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Wed, 31 Jan 2007 15:10:22 +0000 Subject: [PATCH] * 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. --- winsup/cygwin/ChangeLog | 6 ++++++ winsup/cygwin/include/netdb.h | 1 + winsup/cygwin/net.cc | 35 ++++++++++++++++++++++++++++++++++- 3 files changed, 41 insertions(+), 1 deletion(-) diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index ba4a9ff99..2b2c530ea 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,9 @@ +2007-01-31 Corinna Vinschen + + * 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 * fhandler_disk_file.cc (fhandler_disk_file::closedir): Add dir name diff --git a/winsup/cygwin/include/netdb.h b/winsup/cygwin/include/netdb.h index 59c328602..4f2ead1ae 100644 --- a/winsup/cygwin/include/netdb.h +++ b/winsup/cygwin/include/netdb.h @@ -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 diff --git a/winsup/cygwin/net.cc b/winsup/cygwin/net.cc index a28a414f7..5ece8590f 100644 --- a/winsup/cygwin/net.cc +++ b/winsup/cygwin/net.cc @@ -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); }