ws2_32/tests: Add more tests for connection failure.
Signed-off-by: Zebediah Figura <zfigura@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
65dee2d28c
commit
91e4596b9e
|
@ -460,6 +460,71 @@ static void test_poll(void)
|
||||||
ok(out_params->sockets[0].flags == AFD_POLL_CONNECT_ERR, "got flags %#x\n", out_params->sockets[0].flags);
|
ok(out_params->sockets[0].flags == AFD_POLL_CONNECT_ERR, "got flags %#x\n", out_params->sockets[0].flags);
|
||||||
ok(out_params->sockets[0].status == STATUS_CONNECTION_REFUSED, "got status %#x\n", out_params->sockets[0].status);
|
ok(out_params->sockets[0].status == STATUS_CONNECTION_REFUSED, "got status %#x\n", out_params->sockets[0].status);
|
||||||
|
|
||||||
|
in_params->timeout = now.QuadPart;
|
||||||
|
memset(out_params, 0xcc, sizeof(out_buffer));
|
||||||
|
ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, NULL, &io,
|
||||||
|
IOCTL_AFD_POLL, in_params, params_size, out_params, params_size);
|
||||||
|
todo_wine
|
||||||
|
{
|
||||||
|
ok(!ret, "got %#x\n", ret);
|
||||||
|
ok(!io.Status, "got %#x\n", io.Status);
|
||||||
|
ok(io.Information == offsetof(struct afd_poll_params, sockets[1]), "got %#Ix\n", io.Information);
|
||||||
|
ok(out_params->count == 1, "got count %u\n", out_params->count);
|
||||||
|
ok(out_params->sockets[0].socket == client, "got socket %#Ix\n", out_params->sockets[0].socket);
|
||||||
|
ok(out_params->sockets[0].flags == AFD_POLL_CONNECT_ERR, "got flags %#x\n", out_params->sockets[0].flags);
|
||||||
|
ok(out_params->sockets[0].status == STATUS_CONNECTION_REFUSED, "got status %#x\n", out_params->sockets[0].status);
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(out_params, 0xcc, sizeof(out_buffer));
|
||||||
|
ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, NULL, &io,
|
||||||
|
IOCTL_AFD_POLL, in_params, params_size, out_params, params_size);
|
||||||
|
todo_wine
|
||||||
|
{
|
||||||
|
ok(!ret, "got %#x\n", ret);
|
||||||
|
ok(!io.Status, "got %#x\n", io.Status);
|
||||||
|
ok(io.Information == offsetof(struct afd_poll_params, sockets[1]), "got %#Ix\n", io.Information);
|
||||||
|
ok(out_params->count == 1, "got count %u\n", out_params->count);
|
||||||
|
ok(out_params->sockets[0].socket == client, "got socket %#Ix\n", out_params->sockets[0].socket);
|
||||||
|
ok(out_params->sockets[0].flags == AFD_POLL_CONNECT_ERR, "got flags %#x\n", out_params->sockets[0].flags);
|
||||||
|
ok(out_params->sockets[0].status == STATUS_CONNECTION_REFUSED, "got status %#x\n", out_params->sockets[0].status);
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = connect(client, (struct sockaddr *)&addr, sizeof(addr));
|
||||||
|
ok(ret == -1, "got %d\n", ret);
|
||||||
|
todo_wine ok(WSAGetLastError() == WSAEWOULDBLOCK, "got error %u\n", WSAGetLastError());
|
||||||
|
if (WSAGetLastError() == WSAECONNABORTED)
|
||||||
|
{
|
||||||
|
ret = connect(client, (struct sockaddr *)&addr, sizeof(addr));
|
||||||
|
ok(ret == -1, "got %d\n", ret);
|
||||||
|
ok(WSAGetLastError() == WSAEWOULDBLOCK, "got error %u\n", WSAGetLastError());
|
||||||
|
}
|
||||||
|
|
||||||
|
/* A subsequent poll call returns no events, or times out. However, this
|
||||||
|
* can't be reliably tested, as e.g. Linux will fail the connection
|
||||||
|
* immediately. */
|
||||||
|
|
||||||
|
closesocket(client);
|
||||||
|
|
||||||
|
client = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||||
|
|
||||||
|
ret = connect(client, (struct sockaddr *)&addr, sizeof(addr));
|
||||||
|
ok(ret == -1, "expected failure\n");
|
||||||
|
ok(WSAGetLastError() == WSAECONNREFUSED, "got error %u\n", WSAGetLastError());
|
||||||
|
|
||||||
|
memset(out_params, 0xcc, sizeof(out_buffer));
|
||||||
|
ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, NULL, &io,
|
||||||
|
IOCTL_AFD_POLL, in_params, params_size, out_params, params_size);
|
||||||
|
todo_wine
|
||||||
|
{
|
||||||
|
ok(!ret, "got %#x\n", ret);
|
||||||
|
ok(!io.Status, "got %#x\n", io.Status);
|
||||||
|
ok(io.Information == offsetof(struct afd_poll_params, sockets[1]), "got %#Ix\n", io.Information);
|
||||||
|
ok(out_params->count == 1, "got count %u\n", out_params->count);
|
||||||
|
ok(out_params->sockets[0].socket == client, "got socket %#Ix\n", out_params->sockets[0].socket);
|
||||||
|
ok(out_params->sockets[0].flags == AFD_POLL_CONNECT_ERR, "got flags %#x\n", out_params->sockets[0].flags);
|
||||||
|
ok(out_params->sockets[0].status == STATUS_CONNECTION_REFUSED, "got status %#x\n", out_params->sockets[0].status);
|
||||||
|
}
|
||||||
|
|
||||||
closesocket(client);
|
closesocket(client);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1329,6 +1394,27 @@ static void test_get_events(void)
|
||||||
ok(!params.status[i], "got status[%u] %#x\n", i, params.status[i]);
|
ok(!params.status[i], "got status[%u] %#x\n", i, params.status[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ResetEvent(event);
|
||||||
|
ret = WSAEventSelect(client, event, FD_CONNECT);
|
||||||
|
ok(!ret, "got error %u\n", GetLastError());
|
||||||
|
|
||||||
|
ret = WaitForSingleObject(event, 0);
|
||||||
|
ok(ret == WAIT_TIMEOUT, "got %#x\n", ret);
|
||||||
|
|
||||||
|
memset(¶ms, 0xcc, sizeof(params));
|
||||||
|
memset(&io, 0xcc, sizeof(io));
|
||||||
|
ret = NtDeviceIoControlFile((HANDLE)client, NULL, NULL, NULL, &io,
|
||||||
|
IOCTL_AFD_GET_EVENTS, NULL, 0, ¶ms, sizeof(params));
|
||||||
|
ok(!ret, "got %#x\n", ret);
|
||||||
|
ok(!params.flags, "got flags %#x\n", params.flags);
|
||||||
|
for (i = 0; i < ARRAY_SIZE(params.status); ++i)
|
||||||
|
{
|
||||||
|
if (i == AFD_POLL_BIT_CONNECT_ERR)
|
||||||
|
ok(params.status[i] == STATUS_CONNECTION_REFUSED, "got status[%u] %#x\n", i, params.status[i]);
|
||||||
|
else
|
||||||
|
ok(!params.status[i], "got status[%u] %#x\n", i, params.status[i]);
|
||||||
|
}
|
||||||
|
|
||||||
closesocket(client);
|
closesocket(client);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3239,30 +3239,144 @@ static void test_select(void)
|
||||||
ok(ret == 0, "expected 0, got %d\n", ret);
|
ok(ret == 0, "expected 0, got %d\n", ret);
|
||||||
ret = closesocket(fdWrite);
|
ret = closesocket(fdWrite);
|
||||||
ok(ret == 0, "expected 0, got %d\n", ret);
|
ok(ret == 0, "expected 0, got %d\n", ret);
|
||||||
ret = closesocket(fdListen);
|
|
||||||
ok(ret == 0, "expected 0, got %d\n", ret);
|
|
||||||
|
|
||||||
/* w10pro64 sometimes takes over 2 seconds for an error to be reported. */
|
/* w10pro64 sometimes takes over 2 seconds for an error to be reported. */
|
||||||
if (winetest_interactive)
|
if (winetest_interactive)
|
||||||
{
|
{
|
||||||
len = sizeof(address);
|
const struct sockaddr_in invalid_addr =
|
||||||
fdWrite = setup_connector_socket(&address, len, TRUE);
|
{
|
||||||
|
.sin_family = AF_INET,
|
||||||
|
.sin_addr.s_addr = htonl(INADDR_LOOPBACK),
|
||||||
|
.sin_port = 255,
|
||||||
|
};
|
||||||
|
|
||||||
|
fdWrite = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||||
|
set_blocking(fdWrite, FALSE);
|
||||||
|
|
||||||
|
ret = connect(fdWrite, (struct sockaddr *)&invalid_addr, sizeof(invalid_addr));
|
||||||
|
ok(ret == -1, "got %d\n", ret);
|
||||||
|
ok(WSAGetLastError() == WSAEWOULDBLOCK, "got error %u\n", WSAGetLastError());
|
||||||
|
|
||||||
FD_ZERO_ALL();
|
FD_ZERO_ALL();
|
||||||
|
FD_SET(fdWrite, &readfds);
|
||||||
FD_SET(fdWrite, &writefds);
|
FD_SET(fdWrite, &writefds);
|
||||||
FD_SET(fdWrite, &exceptfds);
|
FD_SET(fdWrite, &exceptfds);
|
||||||
select_timeout.tv_sec = 10;
|
select_timeout.tv_sec = 10;
|
||||||
ret = select(0, &readfds, &writefds, &exceptfds, &select_timeout);
|
ret = select(0, &readfds, &writefds, &exceptfds, &select_timeout);
|
||||||
todo_wine ok(ret == 1, "expected 1, got %d\n", ret);
|
todo_wine ok(ret == 1, "expected 1, got %d\n", ret);
|
||||||
|
todo_wine ok(FD_ISSET(fdWrite, &exceptfds), "fdWrite socket is not in the set\n");
|
||||||
|
ok(select_timeout.tv_usec == 250000, "select timeout should not have changed\n");
|
||||||
|
|
||||||
len = sizeof(id);
|
len = sizeof(id);
|
||||||
id = 0xdeadbeef;
|
id = 0xdeadbeef;
|
||||||
ret = getsockopt(fdWrite, SOL_SOCKET, SO_ERROR, (char *)&id, &len);
|
ret = getsockopt(fdWrite, SOL_SOCKET, SO_ERROR, (char *)&id, &len);
|
||||||
ok(!ret, "getsockopt failed with %d\n", WSAGetLastError());
|
ok(!ret, "getsockopt failed with %d\n", WSAGetLastError());
|
||||||
todo_wine ok(id == WSAECONNREFUSED, "got error %u\n", id);
|
todo_wine ok(id == WSAECONNREFUSED, "got error %u\n", id);
|
||||||
|
|
||||||
|
len = sizeof(id);
|
||||||
|
id = 0xdeadbeef;
|
||||||
|
ret = getsockopt(fdWrite, SOL_SOCKET, SO_ERROR, (char *)&id, &len);
|
||||||
|
ok(!ret, "getsockopt failed with %d\n", WSAGetLastError());
|
||||||
|
todo_wine ok(id == WSAECONNREFUSED, "got error %u\n", id);
|
||||||
|
|
||||||
|
FD_ZERO_ALL();
|
||||||
|
FD_SET(fdWrite, &readfds);
|
||||||
|
FD_SET(fdWrite, &writefds);
|
||||||
|
FD_SET(fdWrite, &exceptfds);
|
||||||
|
select_timeout.tv_sec = 10;
|
||||||
|
ret = select(0, &readfds, &writefds, &exceptfds, &select_timeout);
|
||||||
|
todo_wine ok(ret == 1, "got %d\n", ret);
|
||||||
todo_wine ok(FD_ISSET(fdWrite, &exceptfds), "fdWrite socket is not in the set\n");
|
todo_wine ok(FD_ISSET(fdWrite, &exceptfds), "fdWrite socket is not in the set\n");
|
||||||
ok(select_timeout.tv_usec == 250000, "select timeout should not have changed\n");
|
|
||||||
|
/* Calling connect() doesn't reset the socket error, but a successful
|
||||||
|
* connection does. This is kind of tricky to test, because while
|
||||||
|
* Windows takes a couple seconds to actually fail the connection,
|
||||||
|
* Linux will fail the connection almost immediately. */
|
||||||
|
|
||||||
|
ret = connect(fdWrite, (const struct sockaddr *)&invalid_addr, sizeof(invalid_addr));
|
||||||
|
ok(ret == -1, "got %d\n", ret);
|
||||||
|
todo_wine ok(WSAGetLastError() == WSAEWOULDBLOCK, "got error %u\n", WSAGetLastError());
|
||||||
|
if (WSAGetLastError() == WSAECONNABORTED)
|
||||||
|
{
|
||||||
|
ret = connect(fdWrite, (const struct sockaddr *)&invalid_addr, sizeof(invalid_addr));
|
||||||
|
ok(ret == -1, "got %d\n", ret);
|
||||||
|
ok(WSAGetLastError() == WSAEWOULDBLOCK, "got error %u\n", WSAGetLastError());
|
||||||
|
}
|
||||||
|
|
||||||
|
len = sizeof(id);
|
||||||
|
id = 0xdeadbeef;
|
||||||
|
ret = getsockopt(fdWrite, SOL_SOCKET, SO_ERROR, (char *)&id, &len);
|
||||||
|
ok(!ret, "getsockopt failed with %d\n", WSAGetLastError());
|
||||||
|
todo_wine ok(id == WSAECONNREFUSED, "got error %u\n", id);
|
||||||
|
|
||||||
|
FD_ZERO_ALL();
|
||||||
|
FD_SET(fdWrite, &readfds);
|
||||||
|
FD_SET(fdWrite, &writefds);
|
||||||
|
FD_SET(fdWrite, &exceptfds);
|
||||||
|
select_timeout.tv_sec = 10;
|
||||||
|
ret = select(0, &readfds, &writefds, &exceptfds, &select_timeout);
|
||||||
|
todo_wine ok(ret == 1, "got %d\n", ret);
|
||||||
|
todo_wine ok(FD_ISSET(fdWrite, &exceptfds), "fdWrite socket is not in the set\n");
|
||||||
|
|
||||||
|
len = sizeof(address);
|
||||||
|
ret = getsockname(fdListen, (struct sockaddr *)&address, &len);
|
||||||
|
ok(!ret, "got error %u\n", WSAGetLastError());
|
||||||
|
ret = connect(fdWrite, (const struct sockaddr *)&address, sizeof(address));
|
||||||
|
ok(ret == -1, "got %d\n", ret);
|
||||||
|
todo_wine ok(WSAGetLastError() == WSAEWOULDBLOCK, "got error %u\n", WSAGetLastError());
|
||||||
|
if (WSAGetLastError() == WSAECONNABORTED)
|
||||||
|
{
|
||||||
|
ret = connect(fdWrite, (const struct sockaddr *)&address, sizeof(address));
|
||||||
|
ok(ret == -1, "got %d\n", ret);
|
||||||
|
ok(WSAGetLastError() == WSAEWOULDBLOCK, "got error %u\n", WSAGetLastError());
|
||||||
|
}
|
||||||
|
|
||||||
|
FD_ZERO_ALL();
|
||||||
|
FD_SET(fdWrite, &readfds);
|
||||||
|
FD_SET(fdWrite, &writefds);
|
||||||
|
FD_SET(fdWrite, &exceptfds);
|
||||||
|
select_timeout.tv_sec = 1;
|
||||||
|
ret = select(0, &readfds, &writefds, &exceptfds, &select_timeout);
|
||||||
|
ok(ret == 1, "expected 1, got %d\n", ret);
|
||||||
|
ok(FD_ISSET(fdWrite, &writefds), "fdWrite socket is not in the set\n");
|
||||||
|
|
||||||
|
len = sizeof(id);
|
||||||
|
id = 0xdeadbeef;
|
||||||
|
ret = getsockopt(fdWrite, SOL_SOCKET, SO_ERROR, (char *)&id, &len);
|
||||||
|
ok(!ret, "getsockopt failed with %d\n", WSAGetLastError());
|
||||||
|
todo_wine ok(!id, "got error %u\n", id);
|
||||||
|
|
||||||
|
closesocket(fdWrite);
|
||||||
|
|
||||||
|
/* test polling after a (synchronous) failure */
|
||||||
|
|
||||||
|
fdWrite = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||||
|
|
||||||
|
ret = connect(fdWrite, (const struct sockaddr *)&invalid_addr, sizeof(invalid_addr));
|
||||||
|
ok(ret == -1, "got %d\n", ret);
|
||||||
|
ok(WSAGetLastError() == WSAECONNREFUSED, "got error %u\n", WSAGetLastError());
|
||||||
|
|
||||||
|
FD_ZERO_ALL();
|
||||||
|
FD_SET(fdWrite, &readfds);
|
||||||
|
FD_SET(fdWrite, &writefds);
|
||||||
|
FD_SET(fdWrite, &exceptfds);
|
||||||
|
select_timeout.tv_sec = 0;
|
||||||
|
ret = select(0, &readfds, &writefds, &exceptfds, &select_timeout);
|
||||||
|
todo_wine ok(ret == 1, "expected 1, got %d\n", ret);
|
||||||
|
todo_wine ok(FD_ISSET(fdWrite, &exceptfds), "fdWrite socket is not in the set\n");
|
||||||
|
|
||||||
|
len = sizeof(id);
|
||||||
|
id = 0xdeadbeef;
|
||||||
|
ret = getsockopt(fdWrite, SOL_SOCKET, SO_ERROR, (char *)&id, &len);
|
||||||
|
ok(!ret, "getsockopt failed with %d\n", WSAGetLastError());
|
||||||
|
todo_wine ok(!id, "got error %u\n", id);
|
||||||
|
|
||||||
closesocket(fdWrite);
|
closesocket(fdWrite);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ret = closesocket(fdListen);
|
||||||
|
ok(ret == 0, "expected 0, got %d\n", ret);
|
||||||
|
|
||||||
select_timeout.tv_sec = 1;
|
select_timeout.tv_sec = 1;
|
||||||
select_timeout.tv_usec = 250000;
|
select_timeout.tv_usec = 250000;
|
||||||
|
|
||||||
|
@ -6402,6 +6516,33 @@ static void test_WSAPoll(void)
|
||||||
ret = getsockopt(client, SOL_SOCKET, SO_ERROR, (char *)&err, &len);
|
ret = getsockopt(client, SOL_SOCKET, SO_ERROR, (char *)&err, &len);
|
||||||
ok(!ret, "getsockopt failed with %d\n", WSAGetLastError());
|
ok(!ret, "getsockopt failed with %d\n", WSAGetLastError());
|
||||||
todo_wine ok(err == WSAECONNREFUSED, "got error %u\n", err);
|
todo_wine ok(err == WSAECONNREFUSED, "got error %u\n", err);
|
||||||
|
|
||||||
|
len = sizeof(err);
|
||||||
|
err = 0xdeadbeef;
|
||||||
|
ret = getsockopt(client, SOL_SOCKET, SO_ERROR, (char *)&err, &len);
|
||||||
|
ok(!ret, "getsockopt failed with %d\n", WSAGetLastError());
|
||||||
|
todo_wine ok(err == WSAECONNREFUSED, "got error %u\n", err);
|
||||||
|
|
||||||
|
check_poll_todo(client, POLLWRNORM | POLLHUP | POLLERR);
|
||||||
|
|
||||||
|
closesocket(client);
|
||||||
|
|
||||||
|
/* test polling after a (synchronous) failure */
|
||||||
|
|
||||||
|
client = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||||
|
|
||||||
|
ret = connect(client, (const struct sockaddr *)&invalid_addr, sizeof(invalid_addr));
|
||||||
|
ok(ret == -1, "got %d\n", ret);
|
||||||
|
ok(WSAGetLastError() == WSAECONNREFUSED, "got error %u\n", WSAGetLastError());
|
||||||
|
|
||||||
|
check_poll_todo(client, POLLWRNORM | POLLHUP | POLLERR);
|
||||||
|
|
||||||
|
len = sizeof(err);
|
||||||
|
err = 0xdeadbeef;
|
||||||
|
ret = getsockopt(client, SOL_SOCKET, SO_ERROR, (char *)&err, &len);
|
||||||
|
ok(!ret, "getsockopt failed with %d\n", WSAGetLastError());
|
||||||
|
todo_wine ok(!err, "got error %u\n", err);
|
||||||
|
|
||||||
closesocket(client);
|
closesocket(client);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue