From: Bruno Jesus <00cpxxx@gmail.com> Subject: [2/2] ws2_32: Properly implement SO_CONNECT_TIME (try 3) Message-Id: Date: Fri, 24 Oct 2014 00:30:11 -0200 try 3: Simplify the get_connect_time function and ensure that if the server still does not have the connection time (or the server call fails) we will return error and set the time to -1. try 2: Windows tests run so fast that it returns 0 seconds connected, so update the test to allow that value. original: Rebased version of a patch from Erich Hoover, all kudos to him. diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c index 0bcce40..752fe26 100644 --- a/dlls/ws2_32/socket.c +++ b/dlls/ws2_32/socket.c @@ -881,6 +881,19 @@ static NTSTATUS _is_blocking(SOCKET s, BOOL *ret) return status; } +static unsigned int _get_connect_time(SOCKET s) +{ + unsigned int connect_time = 0; + SERVER_START_REQ( get_socket_info ) + { + req->handle = wine_server_obj_handle( SOCKET2HANDLE(s) ); + if (!wine_server_call( req )) + connect_time = reply->connect_time; + } + SERVER_END_REQ; + return connect_time; +} + static unsigned int _get_sock_mask(SOCKET s) { unsigned int ret; @@ -3125,22 +3138,20 @@ 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); + unsigned int connect_time; if (!optlen || *optlen < sizeof(DWORD) || !optval) { SetLastError(WSAEFAULT); return SOCKET_ERROR; } - if (WS_getpeername(s, &addr, &len) == SOCKET_ERROR) + if (WS_getpeername(s, &addr, &len) == SOCKET_ERROR || + !(connect_time = _get_connect_time(s))) *(DWORD *)optval = ~0u; else - { - if (!pretendtime) FIXME("WS_SO_CONNECT_TIME - faking results\n"); - *(DWORD *)optval = pretendtime++; - } + *(DWORD *)optval = (GetTickCount() - connect_time) / 1000; *optlen = sizeof(DWORD); return ret; } diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c index 0ad6e8a..456b474 100644 --- a/dlls/ws2_32/tests/sock.c +++ b/dlls/ws2_32/tests/sock.c @@ -4141,6 +4141,8 @@ static void test_send(void) OVERLAPPED ov; BOOL bret; DWORD id, bytes_sent, dwRet; + socklen_t optlen; + int connect_time; memset(&ov, 0, sizeof(ov)); @@ -4235,6 +4237,18 @@ static void test_send(void) ok(ret == SOCKET_ERROR && WSAGetLastError() == ERROR_IO_PENDING, "Failed to start overlapped send %d - %d\n", ret, WSAGetLastError()); + connect_time = -1; + 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 >= 0, "unexpected connect time %u\n", connect_time); + + connect_time = -1; + 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 >= 0, "unexpected connect time %u\n", connect_time); + end: if (src != INVALID_SOCKET) closesocket(src);