diff options
author | Corinna Vinschen <corinna@vinschen.de> | 2007-01-31 18:10:22 +0300 |
---|---|---|
committer | Corinna Vinschen <corinna@vinschen.de> | 2007-01-31 18:10:22 +0300 |
commit | c2decfdc8a508e3fbc299c67964895ba8d593365 (patch) | |
tree | 7820522b1caa0a73178d9a2606e2ac400142641f /winsup/cygwin/net.cc | |
parent | c3772e717fc3b37fe5db2eac76c4ab907f9f033f (diff) |
* 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.
Diffstat (limited to 'winsup/cygwin/net.cc')
-rw-r--r-- | winsup/cygwin/net.cc | 35 |
1 files changed, 34 insertions, 1 deletions
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); } |