From 2e08b31f7cf2449c90909c1bc46eace80028f8ad Mon Sep 17 00:00:00 2001 From: Bruno Jesus <00cpxxx@gmail.com> Date: Wed, 7 Sep 2011 21:20:37 -0300 Subject: [PATCH] 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 ff3c2821a41..ef2472323e0 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 fd6b8c25809..37661864dcb 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); }