PATCH: getaddrinfo, next try

Marcus Meissner meissner at suse.de
Fri Nov 11 08:52:07 CST 2005


Hi,

Converts hints as requested, also converts address family,
socket type and protocol.

Changelog:
	Implemented getaddrinfo() based on a patch by Mike Hearn.
	Added helper functions for converting address family,
	socket type and protocol.

Index: configure.ac
===================================================================
RCS file: /home/wine/wine/configure.ac,v
retrieving revision 1.412
diff -u -r1.412 configure.ac
--- configure.ac	31 Oct 2005 21:10:38 -0000	1.412
+++ configure.ac	11 Nov 2005 14:49:18 -0000
@@ -1158,6 +1158,7 @@
 	ftruncate \
 	futimes \
 	futimesat \
+	getaddrinfo \
 	getnetbyname \
 	getopt_long \
 	getpagesize \
Index: dlls/winsock/socket.c
===================================================================
RCS file: /home/wine/wine/dlls/winsock/socket.c,v
retrieving revision 1.193
diff -u -r1.193 socket.c
--- dlls/winsock/socket.c	5 Nov 2005 10:43:27 -0000	1.193
+++ dlls/winsock/socket.c	11 Nov 2005 14:49:19 -0000
@@ -3,6 +3,7 @@
  * (ftp.microsoft.com:/Advsys/winsock/spec11/WINSOCK.TXT)
  *
  * Copyright (C) 1993,1994,1996,1997 John Brezak, Erik Bos, Alex Korobka.
+ *           (C) 2005 Mike Hearn
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -285,6 +286,34 @@
     { 0, 0 }
 };
 
+static const int ws_af_map[][2] =
+{
+    MAP_OPTION( AF_INET ),
+    MAP_OPTION( AF_INET6 ),
+#ifdef HAVE_IPX
+    MAP_OPTION( AF_IPX ),
+#endif
+    { 0, 0 }
+};
+
+static const int ws_socktype_map[][2] =
+{
+    MAP_OPTION( SOCK_DGRAM ),
+    MAP_OPTION( SOCK_STREAM ),
+    MAP_OPTION( SOCK_RAW ),
+    { 0, 0 }
+};
+
+static const int ws_proto_map[][2] =
+{
+    MAP_OPTION( IPPROTO_TCP ),
+    MAP_OPTION( IPPROTO_UDP ),
+    MAP_OPTION( IPPROTO_ICMP ),
+    MAP_OPTION( IPPROTO_IGMP ),
+    MAP_OPTION( IPPROTO_RAW ),
+    { 0, 0 }
+};
+
 inline static DWORD NtStatusToWSAError( const DWORD status )
 {
     /* We only need to cover the status codes set by server async request handling */
@@ -658,6 +687,71 @@
   return pfd.revents;
 }
 
+static int
+convert_af_w2u(int windowsaf) {
+    int i;
+
+    for (i=0;ws_af_map[i][0];i++)
+    	if (ws_af_map[i][0] == windowsaf)
+	    return ws_af_map[i][1];
+    FIXME("unhandled Windows address family %d\n", windowsaf);
+    return -1;
+}
+
+static int
+convert_af_u2w(int unixaf) {
+    int i;
+
+    for (i=0;ws_af_map[i][0];i++)
+    	if (ws_af_map[i][1] == unixaf)
+	    return ws_af_map[i][0];
+    FIXME("unhandled UNIX address family %d\n", unixaf);
+    return -1;
+}
+
+static int
+convert_proto_w2u(int windowsproto) {
+    int i;
+
+    for (i=0;ws_proto_map[i][0];i++)
+    	if (ws_proto_map[i][0] == windowsproto)
+	    return ws_proto_map[i][1];
+    FIXME("unhandled Windows socket protocol %d\n", windowsproto);
+    return -1;
+}
+
+static int
+convert_proto_u2w(int unixproto) {
+    int i;
+
+    for (i=0;ws_proto_map[i][0];i++)
+    	if (ws_proto_map[i][1] == unixproto)
+	    return ws_proto_map[i][0];
+    FIXME("unhandled UNIX socket protocol %d\n", unixproto);
+    return -1;
+}
+
+static int
+convert_socktype_w2u(int windowssocktype) {
+    int i;
+
+    for (i=0;ws_socktype_map[i][0];i++)
+    	if (ws_socktype_map[i][0] == windowssocktype)
+	    return ws_socktype_map[i][1];
+    FIXME("unhandled Windows socket type %d\n", windowssocktype);
+    return -1;
+}
+
+static int
+convert_socktype_u2w(int unixsocktype) {
+    int i;
+
+    for (i=0;ws_socktype_map[i][0];i++)
+    	if (ws_socktype_map[i][1] == unixsocktype)
+	    return ws_socktype_map[i][0];
+    FIXME("unhandled UNIX socket type %d\n", unixsocktype);
+    return -1;
+}
 
 /* ----------------------------------- API -----
  *
@@ -2865,6 +2959,132 @@
     return retval;
 }
 
+/***********************************************************************
+ *		freeaddrinfo		(WS2_32.@)
+ */
+void WINAPI WS_freeaddrinfo(struct WS_addrinfo *res)
+{
+    while (res) {
+        struct WS_addrinfo *next;
+
+        if (res->ai_canonname)
+            HeapFree(GetProcessHeap(),0,res->ai_canonname);
+        if (res->ai_addr)
+            HeapFree(GetProcessHeap(),0,res->ai_addr);
+        next = res->ai_next;
+        HeapFree(GetProcessHeap(),0,res);
+        res = next;
+    }
+}
+
+/***********************************************************************
+ *		GetAddrInfoA		(WS2_32.@)
+ *		getaddrinfo		(WS2_32.@)
+ */
+int WINAPI GetAddrInfoA(CHAR *nodename, CHAR *servname,
+                        const struct addrinfo *hints, struct WS_addrinfo **res)
+{
+#if HAVE_GETADDRINFO
+    struct addrinfo *unixaires = NULL;
+    BOOL  node_lowered = FALSE, serv_lowered = FALSE;
+    int   result;
+    struct addrinfo unixhints, *punixhints = NULL;
+    
+    if (nodename) {
+        if (!(nodename = strdup_lower(nodename))) return WSA_NOT_ENOUGH_MEMORY;
+        node_lowered = TRUE;
+    }
+
+    if (servname) {
+        if (!(servname = strdup_lower(servname))) {
+	    if (node_lowered) HeapFree(GetProcessHeap(), 0, nodename);
+	    return WSA_NOT_ENOUGH_MEMORY;
+	}
+        serv_lowered = TRUE;
+    }
+
+    if (hints) {
+    	punixhints = &unixhints;
+	punixhints->ai_flags	= hints->ai_flags;
+	punixhints->ai_family	= convert_af_w2u(hints->ai_family);
+	punixhints->ai_socktype	= convert_socktype_w2u(hints->ai_socktype);
+	punixhints->ai_protocol	= convert_proto_w2u(hints->ai_protocol);
+    }
+
+    /* getaddrinfo(3) is thread safe, no need to wrap in CS */
+    result = getaddrinfo(nodename, servname, punixhints, &unixaires);
+
+    TRACE("%s, %s %p -> %p %d\n", nodename, servname, hints, res, result);
+
+    if (node_lowered) HeapFree(GetProcessHeap(), 0, nodename);
+    if (serv_lowered) HeapFree(GetProcessHeap(), 0, servname);
+
+    if (!result) {
+    	struct addrinfo *xuai = unixaires;
+	struct WS_addrinfo **xai = res;
+
+	*xai = NULL;
+    	while (xuai) {
+	    struct WS_addrinfo *ai = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY, sizeof(struct WS_addrinfo));
+	    int len;
+
+	    if (!ai)
+		goto outofmem;
+
+	    *xai = ai;xai = &ai->ai_next;
+	    ai->ai_flags	= xuai->ai_flags;
+	    ai->ai_family	= convert_af_u2w(xuai->ai_family);
+	    ai->ai_socktype	= convert_socktype_u2w(xuai->ai_socktype);
+	    ai->ai_protocol	= convert_proto_u2w(xuai->ai_protocol);
+	    if (xuai->ai_canonname) {
+		TRACE("canon name - %s\n",debugstr_a(xuai->ai_canonname));
+		ai->ai_canonname = HeapAlloc(GetProcessHeap(),0,strlen(xuai->ai_canonname)+1);
+		if (!ai->ai_canonname)
+		    goto outofmem;
+		strcpy(ai->ai_canonname,xuai->ai_canonname);
+	    }
+	    len = xuai->ai_addrlen;
+	    ai->ai_addr = HeapAlloc(GetProcessHeap(),0,len);
+	    if (!ai->ai_addr)
+		goto outofmem;
+	    ai->ai_addrlen = len;
+	    do {
+		int winlen = ai->ai_addrlen;
+
+		if (!ws_sockaddr_u2ws(xuai->ai_addr, xuai->ai_addrlen, ai->ai_addr, &winlen))
+		    break;
+		len = 2*len;
+		ai->ai_addr = HeapReAlloc(GetProcessHeap(),0,ai->ai_addr,len);
+	    	if (!ai->ai_addr)
+		    goto outofmem;
+		ai->ai_addrlen = len;
+	    } while (1);
+	    xuai = xuai->ai_next;
+	}
+	freeaddrinfo(unixaires);
+    }
+    return result;
+
+outofmem:
+    if (*res) WS_freeaddrinfo(*res);
+    if (unixaires) freeaddrinfo(unixaires);
+    *res = NULL;
+    return WSA_NOT_ENOUGH_MEMORY;
+#else
+    FIXME("getaddrinfo() failed, not found during buildtime.\n");
+    return EAI_FAIL;
+#endif
+}
+
+/***********************************************************************
+ *		GetAddrInfoW		(WS2_32.@)
+ */
+int WINAPI GetAddrInfoW(WCHAR *nodename, WCHAR *servname,
+                        const struct addrinfo *hints, struct addrinfo **res)
+{
+    FIXME("empty stub!\n");
+    return EAI_FAIL;
+}
 
 /***********************************************************************
  *		getservbyport		(WS2_32.56)
Index: dlls/winsock/ws2_32.spec
===================================================================
RCS file: /home/wine/wine/dlls/winsock/ws2_32.spec,v
retrieving revision 1.42
diff -u -r1.42 ws2_32.spec
--- dlls/winsock/ws2_32.spec	1 Aug 2005 10:56:49 -0000	1.42
+++ dlls/winsock/ws2_32.spec	11 Nov 2005 14:49:19 -0000
@@ -113,6 +113,8 @@
 @ stub    WSCUpdateProvider
 @ stub    WSCWriteNameSpaceOrder
 @ stdcall WSCWriteProviderOrder(ptr long)
-@ stub    freeaddrinfo
-@ stub    getaddrinfo
+@ stdcall freeaddrinfo(ptr) WS_freeaddrinfo
+@ stdcall getaddrinfo(str str ptr ptr) GetAddrInfoA
+@ stdcall GetAddrInfoW(wstr wstr ptr ptr)
+@ stdcall GetAddrInfoA(str str ptr ptr)
 @ stub    getnameinfo



More information about the wine-patches mailing list