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