[2/2] ws2_32: Properly implement SO_CONNECT_TIME (try 3)

Bruno Jesus 00cpxxx at gmail.com
Thu Oct 23 21:30:11 CDT 2014


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.
-------------- next part --------------
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);


More information about the wine-patches mailing list