From 924fa2db941095719b476e3b458ced34426401bb Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 22 Sep 2004 22:20:40 +0000 Subject: r2538: Support IPv6 as transport for MSRPC. Tested against Win2k3 Implemented using the POSIX getaddrinfo() call (specified by POSIX 1003.1-2003 and 2553) I'm not sure how portable this function is, so we might have to add a sys_getaddrinfo() later on. (This used to be commit 0fb0530389751c6fb4ca58f5e9a0f23491699f17) --- source4/librpc/rpc/dcerpc_tcp.c | 42 +++++++++++++++++++++++++++++++--------- source4/librpc/rpc/dcerpc_util.c | 4 ++-- 2 files changed, 35 insertions(+), 11 deletions(-) diff --git a/source4/librpc/rpc/dcerpc_tcp.c b/source4/librpc/rpc/dcerpc_tcp.c index 2152c4c5d0..0edc5226a6 100644 --- a/source4/librpc/rpc/dcerpc_tcp.c +++ b/source4/librpc/rpc/dcerpc_tcp.c @@ -280,32 +280,56 @@ static const char *tcp_peer_name(struct dcerpc_pipe *p) */ NTSTATUS dcerpc_pipe_open_tcp(struct dcerpc_pipe **p, const char *server, - uint32_t port) + uint32_t port, + int family) { struct tcp_private *tcp; - int fd; - struct in_addr addr; + int fd, gai_error; struct fd_event fde; + struct addrinfo hints, *res, *tmpres; + char portname[16]; if (port == 0) { port = EPMAPPER_PORT; } - addr.s_addr = interpret_addr(server); - if (addr.s_addr == 0) { + memset(&hints, 0, sizeof(struct addrinfo)); + + hints.ai_family = family; + hints.ai_socktype = SOCK_STREAM; + + snprintf(portname, sizeof(portname)-1, "%d", port); + + gai_error = getaddrinfo(server, portname, &hints, &res); + if (gai_error < 0) + { + DEBUG(0, ("Unable to connect to %s:%d : %s\n", server, port, gai_strerror(gai_error))); return NT_STATUS_BAD_NETWORK_NAME; } - fd = open_socket_out(SOCK_STREAM, &addr, port, 30000); + tmpres = res; + + while (tmpres) { + fd = socket(tmpres->ai_family, tmpres->ai_socktype, tmpres->ai_protocol); + + if(fd >= 0) { + if (connect(fd, tmpres->ai_addr, tmpres->ai_addrlen) == 0) + break; + fd = -1; + } + + tmpres = tmpres->ai_next; + } + + freeaddrinfo(res); + if (fd == -1) { return NT_STATUS_PORT_CONNECTION_REFUSED; } set_socket_options(fd, lp_socket_options()); - set_blocking(fd, False); - - if (!(*p = dcerpc_pipe_init())) { + if (!(*p = dcerpc_pipe_init())) { return NT_STATUS_NO_MEMORY; } diff --git a/source4/librpc/rpc/dcerpc_util.c b/source4/librpc/rpc/dcerpc_util.c index 1898575003..2c9ae0354a 100644 --- a/source4/librpc/rpc/dcerpc_util.c +++ b/source4/librpc/rpc/dcerpc_util.c @@ -69,7 +69,7 @@ NTSTATUS dcerpc_epm_map_tcp_port(const char *server, return NT_STATUS_OK; } - status = dcerpc_pipe_open_tcp(&p, server, EPMAPPER_PORT); + status = dcerpc_pipe_open_tcp(&p, server, EPMAPPER_PORT, AF_UNSPEC ); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -542,7 +542,7 @@ static NTSTATUS dcerpc_pipe_connect_ncacn_ip_tcp(struct dcerpc_pipe **p, DEBUG(1,("Mapped to DCERPC/TCP port %u\n", port)); } - status = dcerpc_pipe_open_tcp(p, binding->host, port); + status = dcerpc_pipe_open_tcp(p, binding->host, port, AF_UNSPEC); if (!NT_STATUS_IS_OK(status)) { DEBUG(0,("Failed to connect to %s:%d\n", binding->host, port)); return status; -- cgit