Module: wine Branch: refs/heads/master Commit: cce073a7774ce3bce339077135c9364a2b3ad966 URL: http://source.winehq.org/git/?p=wine.git;a=commit;h=cce073a7774ce3bce3390771...
Author: Robert Shearman rob@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; }