From: Sebastian Lackner Subject: ws2_32: Implement returning the proper time with SO_CONNECT_TIME. (resend) Message-Id: <54F65729.2070807@fds-team.de> Date: Wed, 04 Mar 2015 01:51:53 +0100 I know that Bruno was also planning to work on this, but haven't seen any attempt since my last submission over three months ago. If there is a better solution for all this, I am pretty sure that it still can be changed later. Based on a patch by Erich Hoover. --- dlls/ws2_32/socket.c | 21 ++++++++++++++++----- dlls/ws2_32/tests/sock.c | 19 +++++++++++++++++++ server/protocol.def | 1 + server/sock.c | 1 + 4 files changed, 37 insertions(+), 5 deletions(-) From 009035006507a9c66cd4a7f3282dd8ad99d927b0 Mon Sep 17 00:00:00 2001 From: Sebastian Lackner Date: Thu, 20 Nov 2014 13:27:24 +0100 Subject: ws2_32: Implement returning the proper time with SO_CONNECT_TIME. Based on a patch by Erich Hoover. --- dlls/ws2_32/socket.c | 21 ++++++++++++++++----- dlls/ws2_32/tests/sock.c | 19 +++++++++++++++++++ server/protocol.def | 1 + server/sock.c | 1 + 4 files changed, 37 insertions(+), 5 deletions(-) diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c index 5bfdecf..440d380 100644 --- a/dlls/ws2_32/socket.c +++ b/dlls/ws2_32/socket.c @@ -923,6 +923,21 @@ static NTSTATUS _is_blocking(SOCKET s, BOOL *ret) return status; } +static DWORD _get_connect_time(SOCKET s) +{ + NTSTATUS status; + DWORD connect_time = ~0u; + SERVER_START_REQ( get_socket_info ) + { + req->handle = wine_server_obj_handle( SOCKET2HANDLE(s) ); + status = wine_server_call( req ); + if (!status) + connect_time = reply->connect_time / -10000000; + } + SERVER_END_REQ; + return connect_time; +} + static unsigned int _get_sock_mask(SOCKET s) { unsigned int ret; @@ -3252,7 +3267,6 @@ INT WINAPI WS_getsockopt(SOCKET s, INT level, case WS_SO_CONNECT_TIME: { - static int pretendtime = 0; struct WS_sockaddr addr; int len = sizeof(addr); @@ -3264,10 +3278,7 @@ INT WINAPI WS_getsockopt(SOCKET s, INT level, if (WS_getpeername(s, &addr, &len) == SOCKET_ERROR) *(DWORD *)optval = ~0u; else - { - if (!pretendtime) FIXME("WS_SO_CONNECT_TIME - faking results\n"); - *(DWORD *)optval = pretendtime++; - } + *(DWORD *)optval = _get_connect_time(s); *optlen = sizeof(DWORD); return ret; } diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c index 19663c2..5cd3b2c 100644 --- a/dlls/ws2_32/tests/sock.c +++ b/dlls/ws2_32/tests/sock.c @@ -4479,6 +4479,8 @@ static void test_send(void) OVERLAPPED ov; BOOL bret; DWORD id, bytes_sent, dwRet; + DWORD expected_time, connect_time; + socklen_t optlen; memset(&ov, 0, sizeof(ov)); @@ -4487,6 +4489,7 @@ static void test_send(void) ok(0, "creating socket pair failed, skipping test\n"); return; } + expected_time = GetTickCount(); set_blocking(dst, FALSE); /* force disable buffering so we can get a pending overlapped request */ @@ -4573,6 +4576,22 @@ static void test_send(void) ok(ret == SOCKET_ERROR && WSAGetLastError() == ERROR_IO_PENDING, "Failed to start overlapped send %d - %d\n", ret, WSAGetLastError()); + expected_time = (GetTickCount() - expected_time) / 1000; + + connect_time = 0xdeadbeef; + optlen = sizeof(connect_time); + ret = getsockopt(dst, SOL_SOCKET, SO_CONNECT_TIME, (char *)&connect_time, &optlen); + ok(!ret, "getsockopt failed %d\n", WSAGetLastError()); + ok(connect_time >= expected_time && connect_time <= expected_time + 1, + "unexpected connect time %u, expected %u\n", connect_time, expected_time); + + connect_time = 0xdeadbeef; + optlen = sizeof(connect_time); + ret = getsockopt(src, SOL_SOCKET, SO_CONNECT_TIME, (char *)&connect_time, &optlen); + ok(!ret, "getsockopt failed %d\n", WSAGetLastError()); + ok(connect_time >= expected_time && connect_time <= expected_time + 1, + "unexpected connect time %u, expected %u\n", connect_time, expected_time); + end: if (src != INVALID_SOCKET) closesocket(src); diff --git a/server/protocol.def b/server/protocol.def index 7ec380b..734bb2f 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -1239,6 +1239,7 @@ enum server_fd_type int family; /* family, see socket manpage */ int type; /* type, see socket manpage */ int protocol; /* protocol, see socket manpage */ + timeout_t connect_time; /* time the socket was connected (relative) */ @END diff --git a/server/sock.c b/server/sock.c index f3bab85..8c9e2e2 100644 --- a/server/sock.c +++ b/server/sock.c @@ -1406,6 +1406,7 @@ DECL_HANDLER(get_socket_info) reply->family = sock->family; reply->type = sock->type; reply->protocol = sock->proto; + reply->connect_time = -(current_time - sock->connect_time); release_object( &sock->obj ); } -- 2.3.0