ws2_32: Fix support for SIO_KEEPALIVE_VALS.

This commit is contained in:
Bruno Jesus 2011-09-07 21:20:37 -03:00 committed by Alexandre Julliard
parent 203d06d410
commit 2e08b31f7c
2 changed files with 41 additions and 6 deletions

View File

@ -3376,8 +3376,8 @@ INT WINAPI WSAIoctl(SOCKET s, DWORD code, LPVOID in_buff, DWORD in_size, LPVOID
k = in_buff; k = in_buff;
keepalive = k->onoff ? 1 : 0; keepalive = k->onoff ? 1 : 0;
keepidle = k->keepalivetime / 1000; keepidle = max( 1, (k->keepalivetime + 500) / 1000 );
keepintvl = k->keepaliveinterval / 1000; keepintvl = max( 1, (k->keepaliveinterval + 500) / 1000 );
TRACE("onoff: %d, keepalivetime: %d, keepaliveinterval: %d\n", keepalive, keepidle, keepintvl); 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) if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (void *)&keepalive, sizeof(int)) == -1)
status = WSAEINVAL; status = WSAEINVAL;
#if defined(TCP_KEEPIDLE) && defined(TCP_KEEPINTVL) #if defined(TCP_KEEPIDLE) && defined(TCP_KEEPINTVL)
else if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE, (void *)&keepidle, sizeof(int)) == -1) /* these values need to be set only if SO_KEEPALIVE is enabled */
status = WSAEINVAL; else if(keepalive)
else if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPINTVL, (void *)&keepintvl, sizeof(int)) == -1) {
status = WSAEINVAL; 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
else else
FIXME("ignoring keepalive interval and timeout\n"); FIXME("ignoring keepalive interval and timeout\n");

View File

@ -53,6 +53,11 @@
ok ( cond tmp, msg, GetCurrentThreadId(), err); \ ok ( cond tmp, msg, GetCurrentThreadId(), err); \
} while (0); } while (0);
#define make_keepalive(k, enable, time, interval) \
k.onoff = enable; \
k.keepalivetime = time; \
k.keepaliveinterval = interval;
/* Function pointers */ /* Function pointers */
static void (WINAPI *pFreeAddrInfoW)(PADDRINFOW) = 0; static void (WINAPI *pFreeAddrInfoW)(PADDRINFOW) = 0;
static int (WINAPI *pGetAddrInfoW)(LPCWSTR,LPCWSTR,const ADDRINFOW *,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) static void test_ioctlsocket(void)
{ {
SOCKET sock; SOCKET sock;
struct tcp_keepalive kalive;
int ret; int ret;
static const LONG cmds[] = {FIONBIO, FIONREAD, SIOCATMARK}; static const LONG cmds[] = {FIONBIO, FIONREAD, SIOCATMARK};
UINT i; UINT i;
@ -2972,6 +2978,31 @@ static void test_ioctlsocket(void)
ret = WSAGetLastError(); ret = WSAGetLastError();
ok(ret == WSAEFAULT || broken(ret == WSAEINVAL), "expected WSAEFAULT, got %d instead\n", ret); 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); closesocket(sock);
} }