Commit 4e6a5d62 authored by Paul Gofman's avatar Paul Gofman Committed by Alexandre Julliard

server: Retry socket connection on ECONNABORTED error.

parent fe9a1403
......@@ -569,13 +569,7 @@ static void test_poll(void)
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());
}
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
......
......@@ -4352,13 +4352,7 @@ static void test_select(void)
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());
}
ok(WSAGetLastError() == WSAEWOULDBLOCK, "got error %u\n", WSAGetLastError());
len = sizeof(id);
id = 0xdeadbeef;
......@@ -4380,13 +4374,7 @@ static void test_select(void)
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());
}
ok(WSAGetLastError() == WSAEWOULDBLOCK, "got error %u\n", WSAGetLastError());
FD_ZERO_ALL();
FD_SET(fdWrite, &readfds);
......@@ -8320,7 +8308,6 @@ static void test_connect(void)
closesocket(connector);
closesocket(acceptor);
closesocket(listener);
tcp_socketpair(&connector, &acceptor);
......@@ -8380,6 +8367,30 @@ static void test_connect(void)
WSACloseEvent(overlapped.hEvent);
closesocket(connector);
/* Test connect after previous connect attempt failure. */
connector = socket(AF_INET, SOCK_STREAM, 0);
ok(connector != INVALID_SOCKET, "failed to create socket, error %u\n", WSAGetLastError());
conaddress.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
conaddress.sin_port = htons(255);
iret = connect(connector, (struct sockaddr *)&conaddress, sizeof(conaddress));
ok(iret == -1, "connection succeeded.\n");
ok(WSAGetLastError() == WSAECONNREFUSED, "got error %u\n", WSAGetLastError());
set_blocking( connector, FALSE );
iret = getsockname(listener, (struct sockaddr*)&address, &addrlen);
ok(!iret, "failed to get address, error %u\n", WSAGetLastError());
iret = connect(connector, (struct sockaddr *)&address, sizeof(address));
ok(iret == -1 && WSAGetLastError() == WSAEWOULDBLOCK, "unexpected iret %d, error %d.\n",
iret, WSAGetLastError());
acceptor = accept(listener, NULL, NULL);
ok(acceptor != INVALID_SOCKET, "could not accept socket error %d\n", WSAGetLastError());
closesocket(acceptor);
closesocket(connector);
closesocket(listener);
}
static void test_AcceptEx(void)
......
......@@ -2602,6 +2602,17 @@ static void sock_ioctl( struct fd *fd, ioctl_code_t code, struct async *async )
unix_addr.in.sin_addr.s_addr = htonl( INADDR_LOOPBACK );
ret = connect( unix_fd, &unix_addr.addr, unix_len );
if (ret < 0 && errno == ECONNABORTED)
{
/* On Linux with nonblocking socket if the previous connect() failed for any reason (including
* timeout), next connect will fail. If the error code was queried by getsockopt( SO_ERROR )
* the error code returned now is ECONNABORTED (otherwise that is the actual connect() failure
* error code). If we got here after previous connect attempt on the socket that means
* we already queried SO_ERROR in sock_error(), so retrying on ECONNABORTED only is
* sufficient. */
ret = connect( unix_fd, &unix_addr.addr, unix_len );
}
if (ret < 0 && errno != EINPROGRESS)
{
set_error( sock_get_ntstatus( errno ) );
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment