[MSAFD] Fix non-blocking sockets support for recv() (#5575) CORE-14486

Currently ReactOS' winsock2 implementation lacks of non-blocking sockets support for recv() apicall, this causes that applications that make use of this feature can lead to unexpected behaviors, one of them is Nginx web server, which uses non-blocking sockets when serving pages through Https protocol.
CORE-14486

It also brings us significantly closer in master head to running Firefox 52, Mypal 29.3.0 and New Moon 28 browser, where the latter allows to connect to mattermost from within ReactOS.
In master head an additional reg file is needed to stop us from exporting specific NT6+ APIs, but in older releases all that should work out of the box with this brilliant patch.


Co-authored-by: Julio Carchi Ruiz <julcar@informaticos.com>
Co-authored-by: Stanislav Motylkov <x86corez@gmail.com>
This commit is contained in:
Julio Carchi 2023-08-17 16:13:13 -05:00 committed by GitHub
parent ab3bd82928
commit 442f5dfab5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 25 additions and 14 deletions

View file

@ -1495,22 +1495,25 @@ WSPAccept(
ListenReceiveData = (PAFD_RECEIVED_ACCEPT_DATA)ReceiveBuffer;
/* If this is non-blocking, make sure there's something for us to accept */
FD_ZERO(&ReadSet);
FD_SET(Socket->Handle, &ReadSet);
Timeout.tv_sec=0;
Timeout.tv_usec=0;
if (WSPSelect(0, &ReadSet, NULL, NULL, &Timeout, lpErrno) == SOCKET_ERROR)
if (Socket->SharedData->NonBlocking)
{
NtClose(SockEvent);
return SOCKET_ERROR;
}
FD_ZERO(&ReadSet);
FD_SET(Socket->Handle, &ReadSet);
Timeout.tv_sec=0;
Timeout.tv_usec=0;
if (ReadSet.fd_array[0] != Socket->Handle)
{
NtClose(SockEvent);
if (lpErrno) *lpErrno = WSAEWOULDBLOCK;
return SOCKET_ERROR;
if (WSPSelect(0, &ReadSet, NULL, NULL, &Timeout, lpErrno) == SOCKET_ERROR)
{
NtClose(SockEvent);
return SOCKET_ERROR;
}
if (ReadSet.fd_array[0] != Socket->Handle)
{
NtClose(SockEvent);
if (lpErrno) *lpErrno = WSAEWOULDBLOCK;
return SOCKET_ERROR;
}
}
/* Send IOCTL */
@ -1782,6 +1785,7 @@ WSPAccept(
AcceptSocketInfo->SharedData->State = SocketConnected;
AcceptSocketInfo->SharedData->ConnectTime = GetCurrentTimeInSeconds();
AcceptSocketInfo->SharedData->NonBlocking = Socket->SharedData->NonBlocking;
/* Return Address in SOCKADDR FORMAT */
if( SocketAddress )

View file

@ -291,6 +291,13 @@ WSPRecv(SOCKET Handle,
NULL,
0);
/* Non-blocking sockets must wait until data is available */
if (Status == STATUS_PENDING && Socket->SharedData->NonBlocking)
{
if (lpErrno) *lpErrno = WSAEWOULDBLOCK;
return SOCKET_ERROR;
}
/* Wait for completion of not overlapped */
if (Status == STATUS_PENDING && lpOverlapped == NULL)
{