https://git.reactos.org/?p=reactos.git;a=commitdiff;h=442f5dfab50da48700a20…
commit 442f5dfab50da48700a20d4bdc6917e48105ad86
Author: Julio Carchi <juliocarchi(a)yahoo.com>
AuthorDate: Thu Aug 17 16:13:13 2023 -0500
Commit: GitHub <noreply(a)github.com>
CommitDate: Thu Aug 17 23:13:13 2023 +0200
[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(a)informaticos.com>
Co-authored-by: Stanislav Motylkov <x86corez(a)gmail.com>
---
dll/win32/msafd/misc/dllmain.c | 32 ++++++++++++++++++--------------
dll/win32/msafd/misc/sndrcv.c | 7 +++++++
2 files changed, 25 insertions(+), 14 deletions(-)
diff --git a/dll/win32/msafd/misc/dllmain.c b/dll/win32/msafd/misc/dllmain.c
index a4cded75c00..79623a142c0 100644
--- a/dll/win32/msafd/misc/dllmain.c
+++ b/dll/win32/msafd/misc/dllmain.c
@@ -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 )
diff --git a/dll/win32/msafd/misc/sndrcv.c b/dll/win32/msafd/misc/sndrcv.c
index 07fe8b1f1c0..06b0afb1d51 100644
--- a/dll/win32/msafd/misc/sndrcv.c
+++ b/dll/win32/msafd/misc/sndrcv.c
@@ -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)
{