ws2_32: Return an error from accept if the address buffer is too small.
This commit is contained in:
parent
9530a06fed
commit
260119e682
|
@ -2247,8 +2247,7 @@ static int WS2_register_async_shutdown( SOCKET s, int type )
|
|||
/***********************************************************************
|
||||
* accept (WS2_32.1)
|
||||
*/
|
||||
SOCKET WINAPI WS_accept(SOCKET s, struct WS_sockaddr *addr,
|
||||
int *addrlen32)
|
||||
SOCKET WINAPI WS_accept(SOCKET s, struct WS_sockaddr *addr, int *addrlen32)
|
||||
{
|
||||
NTSTATUS status;
|
||||
SOCKET as;
|
||||
|
@ -2275,7 +2274,11 @@ SOCKET WINAPI WS_accept(SOCKET s, struct WS_sockaddr *addr,
|
|||
SERVER_END_REQ;
|
||||
if (!status)
|
||||
{
|
||||
if (addr) WS_getpeername(as, addr, addrlen32);
|
||||
if (addr && WS_getpeername(as, addr, addrlen32))
|
||||
{
|
||||
WS_closesocket(as);
|
||||
return SOCKET_ERROR;
|
||||
}
|
||||
return as;
|
||||
}
|
||||
if (is_blocking && status == STATUS_CANT_WAIT)
|
||||
|
|
|
@ -3110,55 +3110,94 @@ static int CALLBACK AlwaysDeferConditionFunc(LPWSABUF lpCallerId, LPWSABUF lpCal
|
|||
return CF_DEFER;
|
||||
}
|
||||
|
||||
static void test_accept(void)
|
||||
static SOCKET setup_server_socket(struct sockaddr_in *addr, int *len)
|
||||
{
|
||||
int ret;
|
||||
SOCKET server_socket = INVALID_SOCKET, accepted = INVALID_SOCKET, connector = INVALID_SOCKET;
|
||||
struct sockaddr_in address;
|
||||
int socklen;
|
||||
select_thread_params thread_params;
|
||||
HANDLE thread_handle = NULL;
|
||||
DWORD id;
|
||||
int ret, val;
|
||||
SOCKET server_socket;
|
||||
|
||||
server_socket = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (server_socket == INVALID_SOCKET)
|
||||
{
|
||||
trace("error creating server socket: %d\n", WSAGetLastError());
|
||||
goto done;
|
||||
return INVALID_SOCKET;
|
||||
}
|
||||
|
||||
val = 1;
|
||||
ret = setsockopt(server_socket, SOL_SOCKET, SO_REUSEADDR, (char *)&val, sizeof(val));
|
||||
if (ret)
|
||||
{
|
||||
trace("error setting SO_REUSEADDR: %d\n", WSAGetLastError());
|
||||
closesocket(server_socket);
|
||||
return INVALID_SOCKET;
|
||||
}
|
||||
|
||||
ret = bind(server_socket, (struct sockaddr *)addr, *len);
|
||||
if (ret)
|
||||
{
|
||||
trace("error binding server socket: %d\n", WSAGetLastError());
|
||||
}
|
||||
|
||||
ret = getsockname(server_socket, (struct sockaddr *)addr, len);
|
||||
if (ret)
|
||||
{
|
||||
skip("failed to lookup bind address: %d\n", WSAGetLastError());
|
||||
closesocket(server_socket);
|
||||
return INVALID_SOCKET;
|
||||
}
|
||||
|
||||
ret = listen(server_socket, 5);
|
||||
if (ret)
|
||||
{
|
||||
trace("error making server socket listen: %d\n", WSAGetLastError());
|
||||
closesocket(server_socket);
|
||||
return INVALID_SOCKET;
|
||||
}
|
||||
|
||||
return server_socket;
|
||||
}
|
||||
|
||||
static SOCKET setup_connector_socket(struct sockaddr_in *addr, int len)
|
||||
{
|
||||
int ret;
|
||||
SOCKET connector;
|
||||
|
||||
connector = socket(AF_INET, SOCK_STREAM, 0);
|
||||
ok(connector != INVALID_SOCKET, "failed to create connector socket %d\n", WSAGetLastError());
|
||||
|
||||
ret = connect(connector, (struct sockaddr *)addr, len);
|
||||
ok(!ret, "connecting to accepting socket failed %d\n", WSAGetLastError());
|
||||
|
||||
return connector;
|
||||
}
|
||||
|
||||
static void test_accept(void)
|
||||
{
|
||||
int ret;
|
||||
SOCKET server_socket, accepted = INVALID_SOCKET, connector;
|
||||
struct sockaddr_in address;
|
||||
SOCKADDR_STORAGE ss;
|
||||
int socklen;
|
||||
select_thread_params thread_params;
|
||||
HANDLE thread_handle = NULL;
|
||||
DWORD id;
|
||||
|
||||
memset(&address, 0, sizeof(address));
|
||||
address.sin_addr.s_addr = inet_addr("127.0.0.1");
|
||||
address.sin_family = AF_INET;
|
||||
ret = bind(server_socket, (struct sockaddr*) &address, sizeof(address));
|
||||
if (ret != 0)
|
||||
{
|
||||
trace("error binding server socket: %d\n", WSAGetLastError());
|
||||
goto done;
|
||||
}
|
||||
|
||||
socklen = sizeof(address);
|
||||
ret = getsockname(server_socket, (struct sockaddr*)&address, &socklen);
|
||||
if (ret != 0) {
|
||||
skip("failed to lookup bind address, error %d\n", WSAGetLastError());
|
||||
goto done;
|
||||
server_socket = setup_server_socket(&address, &socklen);
|
||||
if (server_socket == INVALID_SOCKET)
|
||||
{
|
||||
trace("error creating server socket: %d\n", WSAGetLastError());
|
||||
return;
|
||||
}
|
||||
|
||||
ret = listen(server_socket, 5);
|
||||
if (ret != 0)
|
||||
{
|
||||
trace("error making server socket listen: %d\n", WSAGetLastError());
|
||||
goto done;
|
||||
}
|
||||
connector = setup_connector_socket(&address, socklen);
|
||||
if (connector == INVALID_SOCKET) goto done;
|
||||
|
||||
trace("Blocking accept next\n");
|
||||
|
||||
connector = socket(AF_INET, SOCK_STREAM, 0);
|
||||
ok(connector != INVALID_SOCKET, "Failed to create connector socket, error %d\n", WSAGetLastError());
|
||||
|
||||
ret = connect(connector, (struct sockaddr*)&address, sizeof(address));
|
||||
ok(ret == 0, "connecting to accepting socket failed, error %d\n", WSAGetLastError());
|
||||
|
||||
accepted = WSAAccept(server_socket, NULL, NULL, AlwaysDeferConditionFunc, 0);
|
||||
ok(accepted == INVALID_SOCKET && WSAGetLastError() == WSATRY_AGAIN, "Failed to defer connection, %d\n", WSAGetLastError());
|
||||
|
||||
|
@ -3194,6 +3233,80 @@ static void test_accept(void)
|
|||
ok(thread_params.ReadKilled || broken(!thread_params.ReadKilled) /* Win98/ME, after accept */,
|
||||
"closesocket did not wakeup accept\n");
|
||||
|
||||
closesocket(accepted);
|
||||
closesocket(connector);
|
||||
accepted = connector = server_socket = INVALID_SOCKET;
|
||||
|
||||
socklen = sizeof(address);
|
||||
server_socket = setup_server_socket(&address, &socklen);
|
||||
if (server_socket == INVALID_SOCKET) goto done;
|
||||
|
||||
connector = setup_connector_socket(&address, socklen);
|
||||
if (connector == INVALID_SOCKET) goto done;
|
||||
|
||||
socklen = 0;
|
||||
accepted = WSAAccept(server_socket, (struct sockaddr *)&ss, &socklen, NULL, 0);
|
||||
todo_wine ok(accepted == INVALID_SOCKET && WSAGetLastError() == WSAEFAULT, "got %d\n", WSAGetLastError());
|
||||
ok(!socklen, "got %d\n", socklen);
|
||||
closesocket(connector);
|
||||
connector = INVALID_SOCKET;
|
||||
|
||||
socklen = sizeof(address);
|
||||
connector = setup_connector_socket(&address, socklen);
|
||||
if (connector == INVALID_SOCKET) goto done;
|
||||
|
||||
accepted = WSAAccept(server_socket, NULL, NULL, NULL, 0);
|
||||
ok(accepted != INVALID_SOCKET, "Failed to accept connection, %d\n", WSAGetLastError());
|
||||
closesocket(accepted);
|
||||
closesocket(connector);
|
||||
accepted = connector = INVALID_SOCKET;
|
||||
|
||||
socklen = sizeof(address);
|
||||
connector = setup_connector_socket(&address, socklen);
|
||||
if (connector == INVALID_SOCKET) goto done;
|
||||
|
||||
socklen = sizeof(ss);
|
||||
memset(&ss, 0, sizeof(ss));
|
||||
accepted = WSAAccept(server_socket, (struct sockaddr *)&ss, &socklen, NULL, 0);
|
||||
ok(accepted != INVALID_SOCKET, "Failed to accept connection, %d\n", WSAGetLastError());
|
||||
todo_wine ok(socklen != sizeof(ss), "unexpected length\n");
|
||||
todo_wine ok(ss.ss_family, "family not set\n");
|
||||
closesocket(accepted);
|
||||
closesocket(connector);
|
||||
accepted = connector = INVALID_SOCKET;
|
||||
|
||||
socklen = sizeof(address);
|
||||
connector = setup_connector_socket(&address, socklen);
|
||||
if (connector == INVALID_SOCKET) goto done;
|
||||
|
||||
socklen = 0;
|
||||
accepted = accept(server_socket, (struct sockaddr *)&ss, &socklen);
|
||||
ok(accepted == INVALID_SOCKET && WSAGetLastError() == WSAEFAULT, "got %d\n", WSAGetLastError());
|
||||
ok(!socklen, "got %d\n", socklen);
|
||||
closesocket(connector);
|
||||
accepted = connector = INVALID_SOCKET;
|
||||
|
||||
socklen = sizeof(address);
|
||||
connector = setup_connector_socket(&address, socklen);
|
||||
if (connector == INVALID_SOCKET) goto done;
|
||||
|
||||
accepted = accept(server_socket, NULL, NULL);
|
||||
ok(accepted != INVALID_SOCKET, "Failed to accept connection, %d\n", WSAGetLastError());
|
||||
closesocket(accepted);
|
||||
closesocket(connector);
|
||||
accepted = connector = INVALID_SOCKET;
|
||||
|
||||
socklen = sizeof(address);
|
||||
connector = setup_connector_socket(&address, socklen);
|
||||
if (connector == INVALID_SOCKET) goto done;
|
||||
|
||||
socklen = sizeof(ss);
|
||||
memset(&ss, 0, sizeof(ss));
|
||||
accepted = accept(server_socket, (struct sockaddr *)&ss, &socklen);
|
||||
ok(accepted != INVALID_SOCKET, "Failed to accept connection, %d\n", WSAGetLastError());
|
||||
ok(socklen != sizeof(ss), "unexpected length\n");
|
||||
ok(ss.ss_family, "family not set\n");
|
||||
|
||||
done:
|
||||
if (accepted != INVALID_SOCKET)
|
||||
closesocket(accepted);
|
||||
|
|
Loading…
Reference in New Issue