Robert Shearman : rpcrt4: Use getaddrinfo to get the sockaddr.

Alexandre Julliard julliard at wine.codeweavers.com
Sun May 7 03:36:34 CDT 2006


Module: wine
Branch: refs/heads/master
Commit: cce073a7774ce3bce339077135c9364a2b3ad966
URL:    http://source.winehq.org/git/?p=wine.git;a=commit;h=cce073a7774ce3bce339077135c9364a2b3ad966

Author: Robert Shearman <rob at codeweavers.com>
Date:   Mon May  1 10:37:32 2006 +0100

rpcrt4: Use getaddrinfo to get the sockaddr.

Use getaddrinfo to get the sockaddr to use for connecting to a remote
server as Connection->NetworkAddr may be a hostname as well. Use a
loop to support both IP and IPv6.

---

 dlls/rpcrt4/rpc_transport.c |   68 ++++++++++++++++++++++++++++++++-----------
 1 files changed, 51 insertions(+), 17 deletions(-)

diff --git a/dlls/rpcrt4/rpc_transport.c b/dlls/rpcrt4/rpc_transport.c
index 563a0df..86b4303 100644
--- a/dlls/rpcrt4/rpc_transport.c
+++ b/dlls/rpcrt4/rpc_transport.c
@@ -44,6 +44,9 @@ #endif
 #ifdef HAVE_ARPA_INET_H
 #include <arpa/inet.h>
 #endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
 
 #include "windef.h"
 #include "winbase.h"
@@ -263,8 +266,11 @@ static RpcConnection *rpcrt4_conn_tcp_al
 static RPC_STATUS rpcrt4_ncacn_ip_tcp_open(RpcConnection* Connection)
 {
   RpcConnection_tcp *tcpc = (RpcConnection_tcp *) Connection;
-  struct sockaddr_in sa;
   int sock;
+  int ret;
+  struct addrinfo *ai;
+  struct addrinfo *ai_cur;
+  struct addrinfo hints;
 
   TRACE("(%s, %s)\n", Connection->NetworkAddr, Connection->Endpoint);
 
@@ -277,29 +283,57 @@ static RPC_STATUS rpcrt4_ncacn_ip_tcp_op
   if (tcpc->sock != -1)
     return RPC_S_OK;
 
-  sa.sin_family = AF_INET;
-  inet_pton(AF_INET, Connection->NetworkAddr, &sa.sin_addr);
-  sa.sin_port = htons(atoi(Connection->Endpoint));
-
-  sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
-  if (sock < 0)
+  hints.ai_flags          = 0;
+  hints.ai_family         = PF_UNSPEC;
+  hints.ai_socktype       = SOCK_STREAM;
+  hints.ai_protocol       = IPPROTO_TCP;
+  hints.ai_addrlen        = 0;
+  hints.ai_addr           = NULL;
+  hints.ai_canonname      = NULL;
+  hints.ai_next           = NULL;
+
+  ret = getaddrinfo(Connection->NetworkAddr, Connection->Endpoint, &hints, &ai);
+  if (ret < 0)
   {
-    ERR("socket() failed\n");
-    goto error;
+    ERR("getaddrinfo failed with %d\n", ret);
+    return RPC_S_SERVER_UNAVAILABLE;
   }
 
-  if (0>connect(sock, (struct sockaddr*) &sa, sizeof (sa)))
+  for (ai_cur = ai; ai_cur; ai_cur = ai->ai_next)
   {
-    ERR("connect() failed\n");
-    goto error;
-  }
+    if (TRACE_ON(rpc))
+    {
+      char host[256];
+      char service[256];
+      getnameinfo(ai_cur->ai_addr, ai_cur->ai_addrlen,
+        host, sizeof(host), service, sizeof(service),
+        NI_NUMERICHOST | NI_NUMERICSERV);
+      TRACE("trying %s:%s\n", host, service);
+    }
+
+    sock = socket(ai_cur->ai_family, ai_cur->ai_socktype, ai_cur->ai_protocol);
+    if (sock < 0)
+    {
+      WARN("socket() failed\n");
+      continue;
+    }
 
-  tcpc->sock = sock;
+    if (0>connect(sock, ai_cur->ai_addr, ai_cur->ai_addrlen))
+    {
+      WARN("connect() failed\n");
+      close(sock);
+      continue;
+    }
 
-  return RPC_S_OK;
+    tcpc->sock = sock;
+
+    freeaddrinfo(ai);
+    TRACE("connected\n");
+    return RPC_S_OK;
+  }
 
-error:
-  close(sock);
+  freeaddrinfo(ai);
+  ERR("couldn't connect to %s:%s\n", Connection->NetworkAddr, Connection->Endpoint);
   return RPC_S_SERVER_UNAVAILABLE;
 }
 




More information about the wine-cvs mailing list