[core,proxy] fix BIO read/write methods

Introduced with ae05778644 the return of
BIO_read and BIO_write changed.
Revert this to original behaviour and fix a bug in the proxy code
This commit is contained in:
Armin Novak
2025-07-10 16:01:59 +02:00
committed by akallabeth
parent 19c866b50f
commit e723f8db07
4 changed files with 43 additions and 49 deletions

View File

@@ -38,7 +38,10 @@ extern "C"
* @param userContext user defined context passed by @ref freerdp_set_io_callback_context
* @param data a buffer to read to
* @param bytes the size of the buffer
* @return the number of bytes read or <0 for failures
* @return the number of bytes read. Negative numbers indicate an error
* occurred. \b errno is set accordingly (see man 2 read)
* @bug Before 3.18.0 the function did return \b -1 for transport closed and \b 0 for retry
* events.
* @since version 3.9.0
*/
typedef int (*pTransportLayerRead)(void* userContext, void* data, int bytes);
@@ -48,7 +51,10 @@ extern "C"
* @param userContext user defined context passed by @ref freerdp_set_io_callback_context
* @param data a buffer to write
* @param bytes the size of the buffer
* @return the number of bytes written or <0 for failures
* @return the number of bytes written. Negative numbers indicate an error
* occurred. \b errno is set accordingly (see man 2 send)
* @bug Before 3.18.0 the function did return \b -1 for transport closed and \b 0 for retry
* events.
* @since version 3.9.0
*/
typedef int (*pTransportLayerWrite)(void* userContext, const void* data, int bytes);
@@ -109,14 +115,14 @@ extern "C"
pTransportFkt TLSAccept;
pTransportAttach TransportAttach;
pTransportFkt TransportDisconnect;
pTransportRWFkt ReadPdu; /* Reads a whole PDU from the transport */
pTransportRWFkt WritePdu; /* Writes a whole PDU to the transport */
pTransportRead ReadBytes; /* Reads up to a requested amount of bytes */
pTransportRWFkt ReadPdu; /* Reads a whole PDU from the transport */
pTransportRWFkt WritePdu; /* Writes a whole PDU to the transport */
pTransportRead ReadBytes; /* Reads up to a requested amount of bytes */
pTransportGetPublicKey GetPublicKey; /** @since version 3.2.0 */
pTransportSetBlockingMode SetBlockingMode; /** @since version 3.3.0 */
pTransportConnectLayer ConnectLayer; /** @since 3.9.0 */
pTransportAttachLayer AttachLayer; /** @since 3.9.0 */
UINT64 reserved[64 - 12]; /* Reserve some space for ABI compatibility */
UINT64 reserved[64 - 12]; /* Reserve some space for ABI compatibility */
};
typedef struct rdp_transport_io rdpTransportIo;

View File

@@ -696,12 +696,6 @@ static BOOL http_proxy_connect(rdpContext* context, BIO* bufferedBio, const char
}
Sleep(10);
}
else
{
/* Error? */
WLog_ERR(TAG, "Failed reading reply from HTTP proxy (BIO_read returned zero)");
goto fail;
}
resultsize += WINPR_ASSERTING_INT_CAST(size_t, status);
}

View File

@@ -1354,29 +1354,17 @@ static int freerdp_tcp_layer_read(void* userContext, void* data, int bytes)
rdpTcpLayer* tcpLayer = (rdpTcpLayer*)userContext;
int error = 0;
int status = 0;
(void)WSAResetEvent(tcpLayer->hEvent);
status = _recv((SOCKET)tcpLayer->sockfd, data, bytes, 0);
const int status = _recv((SOCKET)tcpLayer->sockfd, data, bytes, 0);
if (status > 0)
return status;
if (status == 0)
return -1; /* socket closed */
error = WSAGetLastError();
const int error = WSAGetLastError();
if ((error == WSAEWOULDBLOCK) || (error == WSAEINTR) || (error == WSAEINPROGRESS) ||
(error == WSAEALREADY))
{
status = 0;
}
else
{
status = -1;
}
errno = EAGAIN;
return status;
}
@@ -1390,25 +1378,15 @@ static int freerdp_tcp_layer_write(void* userContext, const void* data, int byte
rdpTcpLayer* tcpLayer = (rdpTcpLayer*)userContext;
int error = 0;
int status = 0;
const int status = _send((SOCKET)tcpLayer->sockfd, data, bytes, 0);
if (status > 0)
return status;
status = _send((SOCKET)tcpLayer->sockfd, data, bytes, 0);
const int error = WSAGetLastError();
if (status <= 0)
{
error = WSAGetLastError();
if ((error == WSAEWOULDBLOCK) || (error == WSAEINTR) || (error == WSAEINPROGRESS) ||
(error == WSAEALREADY))
{
status = 0;
}
else
{
status = -1;
}
}
if ((error == WSAEWOULDBLOCK) || (error == WSAEINTR) || (error == WSAEINPROGRESS) ||
(error == WSAEALREADY))
errno = EAGAIN;
return status;
}

View File

@@ -1961,11 +1961,21 @@ static int transport_layer_bio_write(BIO* bio, const char* buf, int size)
BIO_clear_flags(bio, BIO_FLAGS_WRITE | BIO_FLAGS_SHOULD_RETRY);
int status = IFCALLRESULT(-1, layer->Write, layer->userContext, buf, size);
errno = 0;
const int status = IFCALLRESULT(-1, layer->Write, layer->userContext, buf, size);
if (status >= 0 && status < size)
BIO_set_flags(bio, (BIO_FLAGS_WRITE | BIO_FLAGS_SHOULD_RETRY));
switch (errno)
{
case EAGAIN:
BIO_set_flags(bio, (BIO_FLAGS_WRITE | BIO_FLAGS_SHOULD_RETRY));
break;
default:
break;
}
return status;
}
@@ -1983,11 +1993,17 @@ static int transport_layer_bio_read(BIO* bio, char* buf, int size)
return -1;
BIO_clear_flags(bio, BIO_FLAGS_READ | BIO_FLAGS_SHOULD_RETRY);
errno = 0;
const int status = IFCALLRESULT(-1, layer->Read, layer->userContext, buf, size);
int status = IFCALLRESULT(-1, layer->Read, layer->userContext, buf, size);
if (status == 0)
BIO_set_flags(bio, (BIO_FLAGS_READ | BIO_FLAGS_SHOULD_RETRY));
switch (errno)
{
case EAGAIN:
BIO_set_flags(bio, (BIO_FLAGS_READ | BIO_FLAGS_SHOULD_RETRY));
break;
default:
break;
}
return status;
}