GUACAMOLE-249: Gradually reassemble received chunks of RDPSND data.

This commit is contained in:
Michael Jumper 2019-12-21 22:51:43 -08:00
parent a7352b1429
commit 7b93b3d2e9
2 changed files with 54 additions and 3 deletions

View File

@ -161,9 +161,45 @@ static VOID guac_rdpsnd_handle_open_event(LPVOID user_param,
return; return;
} }
wStream* input_stream = Stream_New(data, data_length); /* If receiving first chunk, allocate sufficient space for all remaining
guac_rdpsnd_process_receive(rdpsnd, input_stream); * chunks */
Stream_Free(input_stream, FALSE); if (data_flags & CHANNEL_FLAG_FIRST) {
/* Limit maximum received size */
if (total_length > GUAC_SVC_MAX_ASSEMBLED_LENGTH) {
guac_client_log(rdpsnd->client, GUAC_LOG_WARNING, "RDP server has "
"requested to send a sequence of %i bytes, but this "
"exceeds the maximum buffer space of %i bytes. Received "
"data may be truncated.", total_length,
GUAC_SVC_MAX_ASSEMBLED_LENGTH);
total_length = GUAC_SVC_MAX_ASSEMBLED_LENGTH;
}
rdpsnd->input_stream = Stream_New(NULL, total_length);
}
/* Add chunk to buffer only if sufficient space remains */
if (Stream_EnsureRemainingCapacity(rdpsnd->input_stream, data_length))
Stream_Write(rdpsnd->input_stream, data, data_length);
else
guac_client_log(rdpsnd->client, GUAC_LOG_WARNING, "%i bytes of data "
"received from within the remote desktop session for the "
"RDPSND channel are being dropped because the maximum "
"available space for received data has been exceeded.",
data_length, rdpsnd->channel_def.name, open_handle,
rdpsnd->open_handle);
/* Fire event once last chunk has been received */
if (data_flags & CHANNEL_FLAG_LAST) {
Stream_SealLength(rdpsnd->input_stream);
Stream_SetPosition(rdpsnd->input_stream, 0);
guac_rdpsnd_process_receive(rdpsnd, rdpsnd->input_stream);
Stream_Free(rdpsnd->input_stream, TRUE);
}
} }

View File

@ -34,6 +34,13 @@
*/ */
#define GUAC_RDP_MAX_FORMATS 16 #define GUAC_RDP_MAX_FORMATS 16
/**
* The maximum number of bytes that the RDP server will be allowed to send
* within any single write operation, regardless of the number of chunks that
* write is split into. Bytes beyond this limit may be dropped.
*/
#define GUAC_SVC_MAX_ASSEMBLED_LENGTH 1048576
/** /**
* Abstract representation of a PCM format, including the sample rate, number * Abstract representation of a PCM format, including the sample rate, number
* of channels, and bits per sample. * of channels, and bits per sample.
@ -103,6 +110,14 @@ typedef struct guac_rdpsnd {
*/ */
DWORD open_handle; DWORD open_handle;
/**
* All data that has been received thus far from the current RDP server
* write operation. Data received along virtual channels is sent in chunks
* (typically 1600 bytes), and thus must be gradually reassembled as it is
* received.
*/
wStream* input_stream;
/** /**
* The block number of the last SNDC_WAVE (WaveInfo) PDU received. * The block number of the last SNDC_WAVE (WaveInfo) PDU received.
*/ */