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