diff options
author | Simon Josefsson <simon@josefsson.org> | 2006-06-22 13:05:34 +0000 |
---|---|---|
committer | Simon Josefsson <simon@josefsson.org> | 2006-06-22 13:05:34 +0000 |
commit | 09462d24ae58ea981b44f19557065ae1f25f068c (patch) | |
tree | 215dc1bef17f6f26a211bb03025116e45650e579 /gl | |
parent | 93b6228754b1cb22c4b95480b34bbdbafd2fa1e1 (diff) | |
download | gnutls-09462d24ae58ea981b44f19557065ae1f25f068c.tar.gz |
Try new win32 hooks for getaddrinfo.
Diffstat (limited to 'gl')
-rw-r--r-- | gl/getaddrinfo.c | 81 | ||||
-rw-r--r-- | gl/getaddrinfo.h | 11 | ||||
-rw-r--r-- | gl/m4/getaddrinfo.m4 | 2 | ||||
-rw-r--r-- | gl/socket_.h | 4 |
4 files changed, 94 insertions, 4 deletions
diff --git a/gl/getaddrinfo.c b/gl/getaddrinfo.c index 9ebca0c0e0..f90e835787 100644 --- a/gl/getaddrinfo.c +++ b/gl/getaddrinfo.c @@ -1,5 +1,5 @@ /* Get address information (partial implementation). - Copyright (C) 1997, 2001, 2002, 2004, 2005 Free Software Foundation, Inc. + Copyright (C) 1997, 2001, 2002, 2004, 2005, 2006 Free Software Foundation, Inc. Contributed by Simon Josefsson <simon@josefsson.org>. This program is free software; you can redistribute it and/or modify @@ -57,6 +57,61 @@ validate_family (int family) return false; } +#ifdef _WIN32 +typedef int WSAAPI (*getaddrinfo_func) (const char FAR* nodename, + const char FAR* servname, + const struct addrinfo FAR* hints, + struct addrinfo FAR** res); +typedef void (*freeaddrinfo_func) (struct addrinfo* ai); + +typedef int WSAAPI (*getnameinfo_func) (const struct sockaddr FAR* sa, + socklen_t salen, + char FAR* host, + DWORD hostlen, + char FAR* serv, + DWORD servlen, + int flags); + +static getaddrinfo_func getaddrinfo_ptr = NULL; +static freeaddrinfo_func freeaddrinfo_ptr = NULL; +static getnameinfo_func getnameinfo_ptr = NULL; + +int use_win32_p (void) +{ + static int done = 0; + HMODULE h; + + if (done) + return 0; + + done = 1; + + h = GetModuleHandle ("ws2_32.dll"); + + if (h) + { + getaddrinfo_ptr = GetProcAddress (h, "getaddrinfo"); + freeaddrinfo_ptr = GetProcAddress (h, "freeaddrinfo"); + getnameinfo_ptr = GetProcAddress (h, "getnameinfo"); + } + + /* Make sure we don't mix getaddrinfo and freeaddrinfo + implementations. */ + if ((getaddrinfo_ptr && !freeaddrinfo_ptr) || + (!getaddrinfo_ptr && freeaddrinfo_ptr)) + { + getaddrinfo_ptr = NULL; + freeaddrinfo_ptr = NULL; + } + + /* If either one is missing, something is odd. */ + if (!getaddrinfo_ptr || !getnameinfo_ptr) + return 0; + + return 1; +} +#endif + /* Translate name of a service location and/or a service name to set of socket addresses. */ int @@ -83,6 +138,11 @@ getaddrinfo (const char *restrict nodename, }; #endif +#ifdef _WIN32 + if (use_win32_p ()) + return getaddrinfo_ptr (nodename, servname, hints, res); +#endif + if (hints && (hints->ai_flags & ~AI_CANONNAME)) /* FIXME: Support more flags. */ return EAI_BADFLAGS; @@ -225,6 +285,11 @@ getaddrinfo (const char *restrict nodename, void freeaddrinfo (struct addrinfo *ai) { +#ifdef _WIN32 + if (use_win32_p ()) + return freeaddrinfo_ptr (ai); +#endif + while (ai) { struct addrinfo *cur; @@ -236,3 +301,17 @@ freeaddrinfo (struct addrinfo *ai) free (cur); } } + +int getnameinfo(const struct sockaddr *restrict sa, socklen_t salen, + char *restrict node, socklen_t nodelen, + char *restrict service, socklen_t servicelen, + int flags) +{ +#ifdef _WIN32 + if (use_win32_p ()) + return getnameinfo_ptr (sa, salen, node, nodelen, + service, servicelen, flags); +#endif + + return EAI_FAIL; +} diff --git a/gl/getaddrinfo.h b/gl/getaddrinfo.h index eb0b718c37..eb8c787a62 100644 --- a/gl/getaddrinfo.h +++ b/gl/getaddrinfo.h @@ -117,4 +117,15 @@ extern void freeaddrinfo (struct addrinfo *ai); extern const char *gai_strerror (int ecode); # endif +# if !HAVE_DECL_GETNAMEINFO +/* Convert socket address to printable node and service names. + For more details, see the POSIX:2001 specification + <http://www.opengroup.org/susv3xsh/gai_strerror.html>. */ +extern int getnameinfo(const struct sockaddr *restrict sa, socklen_t salen, + char *restrict node, socklen_t nodelen, + char *restrict service, socklen_t servicelen, + int flags); + +# endif + #endif /* GETADDRINFO_H */ diff --git a/gl/m4/getaddrinfo.m4 b/gl/m4/getaddrinfo.m4 index fef311ff18..4aac48915a 100644 --- a/gl/m4/getaddrinfo.m4 +++ b/gl/m4/getaddrinfo.m4 @@ -58,7 +58,7 @@ AC_DEFUN([gl_PREREQ_GETADDRINFO], [ AC_REQUIRE([AC_C_INLINE]) AC_REQUIRE([AC_GNU_SOURCE]) AC_CHECK_HEADERS_ONCE(netinet/in.h netdb.h) - AC_CHECK_DECLS([getaddrinfo, freeaddrinfo, gai_strerror],,,[ + AC_CHECK_DECLS([getaddrinfo, freeaddrinfo, gai_strerror, getnameinfo],,,[ /* sys/types.h is not needed according to POSIX, but the sys/socket.h in i386-unknown-freebsd4.10 and powerpc-apple-darwin5.5 required it. */ diff --git a/gl/socket_.h b/gl/socket_.h index 715d0ad0b8..d5e1e599ff 100644 --- a/gl/socket_.h +++ b/gl/socket_.h @@ -24,13 +24,13 @@ needed by an application. Currently only MinGW is supported. See the gnulib manual regarding - Windows sockets. MinGW have the header files winsock2.h and + Windows sockets. MinGW has the header files winsock2.h and ws2tcpip.h that declare the sys/socket.h definitions we need. Note that you can influence which definitions you get by setting the WINVER symbol before including these two files. For example, getaddrinfo is only available if _WIN32_WINNT >= 0x0501 (that symbol is set indiriectly through WINVER). You can set this by - adding AC_DEFIN(WINVER, 0x0501) to configure.ac. Note that your + adding AC_DEFINE(WINVER, 0x0501) to configure.ac. Note that your code may not run on older Windows releases then. My Windows 2000 box was not able to run the code, for example. The situation is slightly confusing because: |