summaryrefslogtreecommitdiff
path: root/gl
diff options
context:
space:
mode:
authorSimon Josefsson <simon@josefsson.org>2006-06-22 13:05:34 +0000
committerSimon Josefsson <simon@josefsson.org>2006-06-22 13:05:34 +0000
commit09462d24ae58ea981b44f19557065ae1f25f068c (patch)
tree215dc1bef17f6f26a211bb03025116e45650e579 /gl
parent93b6228754b1cb22c4b95480b34bbdbafd2fa1e1 (diff)
downloadgnutls-09462d24ae58ea981b44f19557065ae1f25f068c.tar.gz
Try new win32 hooks for getaddrinfo.
Diffstat (limited to 'gl')
-rw-r--r--gl/getaddrinfo.c81
-rw-r--r--gl/getaddrinfo.h11
-rw-r--r--gl/m4/getaddrinfo.m42
-rw-r--r--gl/socket_.h4
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: