Modified transport_check_fds to deliver all available PDUs before returning to the caller. This prevents the caller from waiting indefinitely for a socket to get signalled that data is available. It fixes a problem with Microsoft mobile clients connecting to FreeRDS whereby the client places both the MCS Erect Domain and MCS Attach User PDUs into the same ethernet frame. As a result, FreeRDS was only processing the first PDU and then blocking indefinitely waiting for data to arrive on the socket.

This commit is contained in:
Mike McDonald 2014-03-10 15:35:14 -04:00
parent b4b6a2171d
commit 1daea0d0dc
1 changed files with 116 additions and 106 deletions

View File

@ -853,9 +853,18 @@ int transport_check_fds(rdpTransport* transport)
#endif #endif
ResetEvent(transport->ReceiveEvent); ResetEvent(transport->ReceiveEvent);
/**
* Loop through and read all available PDUs. Since multiple
* PDUs can exist, it's important to deliver them all before
* returning. Otherwise we run the risk of having a thread
* wait for a socket to get signalled that data is available
* (which may never happen).
*/
for (;;)
{
status = transport_read_nonblocking(transport); status = transport_read_nonblocking(transport);
if (status < 0) if (status <= 0)
return status; return status;
while ((pos = Stream_GetPosition(transport->ReceiveBuffer)) > 0) while ((pos = Stream_GetPosition(transport->ReceiveBuffer)) > 0)
@ -963,6 +972,7 @@ int transport_check_fds(rdpTransport* transport)
if (status < 0) if (status < 0)
return status; return status;
} }
}
return 0; return 0;
} }