Bruno Jesus : ws2_32: Fix support for SIO_KEEPALIVE_VALS.

Alexandre Julliard julliard at winehq.org
Thu Sep 8 14:52:11 CDT 2011


Module: wine
Branch: master
Commit: 2e08b31f7cf2449c90909c1bc46eace80028f8ad
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=2e08b31f7cf2449c90909c1bc46eace80028f8ad

Author: Bruno Jesus <00cpxxx at gmail.com>
Date:   Wed Sep  7 21:20:37 2011 -0300

ws2_32: Fix support for SIO_KEEPALIVE_VALS.

---

 dlls/ws2_32/socket.c     |   16 ++++++++++------
 dlls/ws2_32/tests/sock.c |   31 +++++++++++++++++++++++++++++++
 2 files changed, 41 insertions(+), 6 deletions(-)

diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c
index ff3c282..ef24723 100644
--- a/dlls/ws2_32/socket.c
+++ b/dlls/ws2_32/socket.c
@@ -3376,8 +3376,8 @@ INT WINAPI WSAIoctl(SOCKET s, DWORD code, LPVOID in_buff, DWORD in_size, LPVOID
 
         k = in_buff;
         keepalive = k->onoff ? 1 : 0;
-        keepidle = k->keepalivetime / 1000;
-        keepintvl = k->keepaliveinterval / 1000;
+        keepidle = max( 1, (k->keepalivetime + 500) / 1000 );
+        keepintvl = max( 1, (k->keepaliveinterval + 500) / 1000 );
 
         TRACE("onoff: %d, keepalivetime: %d, keepaliveinterval: %d\n", keepalive, keepidle, keepintvl);
 
@@ -3385,10 +3385,14 @@ INT WINAPI WSAIoctl(SOCKET s, DWORD code, LPVOID in_buff, DWORD in_size, LPVOID
         if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (void *)&keepalive, sizeof(int)) == -1)
             status = WSAEINVAL;
 #if defined(TCP_KEEPIDLE) && defined(TCP_KEEPINTVL)
-        else if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE, (void *)&keepidle, sizeof(int)) == -1)
-            status = WSAEINVAL;
-        else if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPINTVL, (void *)&keepintvl, sizeof(int)) == -1)
-            status = WSAEINVAL;
+        /* these values need to be set only if SO_KEEPALIVE is enabled */
+        else if(keepalive)
+        {
+            if (keepidle && setsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE, (void *)&keepidle, sizeof(int)) == -1)
+                status = WSAEINVAL;
+            else if (keepintvl && setsockopt(fd, IPPROTO_TCP, TCP_KEEPINTVL, (void *)&keepintvl, sizeof(int)) == -1)
+                status = WSAEINVAL;
+        }
 #else
         else
             FIXME("ignoring keepalive interval and timeout\n");
diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c
index fd6b8c2..3766186 100644
--- a/dlls/ws2_32/tests/sock.c
+++ b/dlls/ws2_32/tests/sock.c
@@ -53,6 +53,11 @@
         ok ( cond tmp, msg, GetCurrentThreadId(), err); \
    } while (0);
 
+#define make_keepalive(k, enable, time, interval) \
+   k.onoff = enable; \
+   k.keepalivetime = time; \
+   k.keepaliveinterval = interval;
+
 /* Function pointers */
 static void   (WINAPI  *pFreeAddrInfoW)(PADDRINFOW) = 0;
 static int    (WINAPI  *pGetAddrInfoW)(LPCWSTR,LPCWSTR,const ADDRINFOW *,PADDRINFOW *) = 0;
@@ -2933,6 +2938,7 @@ static void test_addr_to_print(void)
 static void test_ioctlsocket(void)
 {
     SOCKET sock;
+    struct tcp_keepalive kalive;
     int ret;
     static const LONG cmds[] = {FIONBIO, FIONREAD, SIOCATMARK};
     UINT i;
@@ -2972,6 +2978,31 @@ static void test_ioctlsocket(void)
     ret = WSAGetLastError();
     ok(ret == WSAEFAULT || broken(ret == WSAEINVAL), "expected WSAEFAULT, got %d instead\n", ret);
 
+    /* broken used to catch W95, W98, NT4 */
+    make_keepalive(kalive, 0, 0, 0);
+    ret = WSAIoctl(sock, SIO_KEEPALIVE_VALS, &kalive, sizeof(struct tcp_keepalive), NULL, 0, &arg, NULL, NULL);
+    ok(ret == 0 || broken(ret == SOCKET_ERROR), "WSAIoctl failed unexpectedly\n");
+
+    make_keepalive(kalive, 1, 0, 0);
+    ret = WSAIoctl(sock, SIO_KEEPALIVE_VALS, &kalive, sizeof(struct tcp_keepalive), NULL, 0, &arg, NULL, NULL);
+    ok(ret == 0 || broken(ret == SOCKET_ERROR), "WSAIoctl failed unexpectedly\n");
+
+    make_keepalive(kalive, 1, 1000, 1000);
+    ret = WSAIoctl(sock, SIO_KEEPALIVE_VALS, &kalive, sizeof(struct tcp_keepalive), NULL, 0, &arg, NULL, NULL);
+    ok(ret == 0 || broken(ret == SOCKET_ERROR), "WSAIoctl failed unexpectedly\n");
+
+    make_keepalive(kalive, 1, 10000, 10000);
+    ret = WSAIoctl(sock, SIO_KEEPALIVE_VALS, &kalive, sizeof(struct tcp_keepalive), NULL, 0, &arg, NULL, NULL);
+    ok(ret == 0 || broken(ret == SOCKET_ERROR), "WSAIoctl failed unexpectedly\n");
+
+    make_keepalive(kalive, 1, 100, 100);
+    ret = WSAIoctl(sock, SIO_KEEPALIVE_VALS, &kalive, sizeof(struct tcp_keepalive), NULL, 0, &arg, NULL, NULL);
+    ok(ret == 0 || broken(ret == SOCKET_ERROR), "WSAIoctl failed unexpectedly\n");
+
+    make_keepalive(kalive, 0, 100, 100);
+    ret = WSAIoctl(sock, SIO_KEEPALIVE_VALS, &kalive, sizeof(struct tcp_keepalive), NULL, 0, &arg, NULL, NULL);
+    ok(ret == 0 || broken(ret == SOCKET_ERROR), "WSAIoctl failed unexpectedly\n");
+
     closesocket(sock);
 }
 




More information about the wine-cvs mailing list