Module: wine Branch: master Commit: a42d4dbfb6dd6c6bb7c271692ad26a870df54be9 URL: http://source.winehq.org/git/wine.git/?a=commit;h=a42d4dbfb6dd6c6bb7c271692a...
Author: Rob Shearman robertshearman@gmail.com Date: Thu Mar 26 13:35:43 2009 +0000
rpcrt4: Allow listening on dynamically generated ncacn_ip_tcp endpoints.
---
dlls/rpcrt4/rpc_transport.c | 31 ++++++++++++++++++++++++++++--- dlls/rpcrt4/tests/rpc_protseq.c | 2 -- 2 files changed, 28 insertions(+), 5 deletions(-)
diff --git a/dlls/rpcrt4/rpc_transport.c b/dlls/rpcrt4/rpc_transport.c index e308564..b01228b 100644 --- a/dlls/rpcrt4/rpc_transport.c +++ b/dlls/rpcrt4/rpc_transport.c @@ -884,7 +884,7 @@ static RPC_STATUS rpcrt4_protseq_ncacn_ip_tcp_open_endpoint(RpcServerProtseq *pr hints.ai_canonname = NULL; hints.ai_next = NULL;
- ret = getaddrinfo(NULL, endpoint, &hints, &ai); + ret = getaddrinfo(NULL, endpoint ? endpoint : "0", &hints, &ai); if (ret) { ERR("getaddrinfo for port %s failed: %s\n", endpoint, @@ -898,11 +898,13 @@ static RPC_STATUS rpcrt4_protseq_ncacn_ip_tcp_open_endpoint(RpcServerProtseq *pr { RpcConnection_tcp *tcpc; RPC_STATUS create_status; + struct sockaddr_storage sa; + socklen_t sa_len; + char service[NI_MAXSERV];
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); @@ -928,9 +930,28 @@ static RPC_STATUS rpcrt4_protseq_ncacn_ip_tcp_open_endpoint(RpcServerProtseq *pr status = RPC_S_CANT_CREATE_ENDPOINT; continue; } + + sa_len = sizeof(sa); + if (getsockname(sock, (struct sockaddr *)&sa, &sa_len)) + { + WARN("getsockname() failed: %s\n", strerror(errno)); + status = RPC_S_CANT_CREATE_ENDPOINT; + continue; + } + + ret = getnameinfo((struct sockaddr *)&sa, sa_len, + NULL, 0, service, sizeof(service), + NI_NUMERICSERV); + if (ret) + { + WARN("getnameinfo failed: %s\n", gai_strerror(ret)); + status = RPC_S_CANT_CREATE_ENDPOINT; + continue; + } + create_status = RPCRT4_CreateConnection((RpcConnection **)&tcpc, TRUE, protseq->Protseq, NULL, - endpoint, NULL, NULL, NULL); + service, NULL, NULL, NULL); if (create_status != RPC_S_OK) { closesocket(sock); @@ -962,6 +983,10 @@ static RPC_STATUS rpcrt4_protseq_ncacn_ip_tcp_open_endpoint(RpcServerProtseq *pr
tcpc->common.Next = first_connection; first_connection = &tcpc->common; + + /* since IPv4 and IPv6 share the same port space, we only need one + * successful bind to listen for both */ + break; }
freeaddrinfo(ai); diff --git a/dlls/rpcrt4/tests/rpc_protseq.c b/dlls/rpcrt4/tests/rpc_protseq.c index a9b98a0..06a82ec 100644 --- a/dlls/rpcrt4/tests/rpc_protseq.c +++ b/dlls/rpcrt4/tests/rpc_protseq.c @@ -69,7 +69,6 @@ static void test_RpcServerUseProtseq(void) if (status == RPC_S_OK) endpoints_registered++;
status = RpcServerUseProtseq(iptcp, 0, NULL); - todo_wine ok(status == RPC_S_OK, "RpcServerUseProtseq(ncacn_ip_tcp) failed with status %d\n", status); if (status == RPC_S_OK) endpoints_registered++;
@@ -101,7 +100,6 @@ static void test_RpcServerUseProtseq(void) ok(status == RPC_S_OK, "RpcServerUseProtseq(ncacn_np) failed with status %d\n", status);
status = RpcServerUseProtseq(iptcp, 0, NULL); - todo_wine ok(status == RPC_S_OK, "RpcServerUseProtseq(ncacn_ip_tcp) failed with status %d\n", status);
status = RpcServerUseProtseq(ncalrpc, 0, NULL);