mirror of https://github.com/FreeRDP/FreeRDP
Refactored rdpFastpath
* Structure now opaque * Added WINPR_ASSERT where appropriate
This commit is contained in:
parent
c17ba281a3
commit
64403d9d40
|
@ -29,6 +29,7 @@
|
|||
#include <string.h>
|
||||
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/assert.h>
|
||||
#include <winpr/stream.h>
|
||||
|
||||
#include <freerdp/api.h>
|
||||
|
@ -47,6 +48,16 @@
|
|||
|
||||
#define TAG FREERDP_TAG("core.fastpath")
|
||||
|
||||
struct rdp_fastpath
|
||||
{
|
||||
rdpRdp* rdp;
|
||||
wStream* fs;
|
||||
BYTE encryptionFlags;
|
||||
BYTE numberEvents;
|
||||
wStream* updateData;
|
||||
int fragmentation;
|
||||
};
|
||||
|
||||
/**
|
||||
* Fast-Path packet format is defined in [MS-RDPBCGR] 2.2.9.1.2, which revises
|
||||
* server output packets from the first byte with the goal of improving
|
||||
|
@ -80,52 +91,6 @@ static const char* fastpath_update_to_string(UINT8 update)
|
|||
return FASTPATH_UPDATETYPE_STRINGS[update];
|
||||
}
|
||||
|
||||
/*
|
||||
* The fastpath header may be two or three bytes long.
|
||||
* This function assumes that at least two bytes are available in the stream
|
||||
* and doesn't touch third byte.
|
||||
*/
|
||||
UINT16 fastpath_header_length(wStream* s)
|
||||
{
|
||||
BYTE length1;
|
||||
|
||||
if (!s || (Stream_GetRemainingLength(s) < 2))
|
||||
return 0;
|
||||
|
||||
Stream_Seek_UINT8(s);
|
||||
Stream_Read_UINT8(s, length1);
|
||||
Stream_Rewind(s, 2);
|
||||
return ((length1 & 0x80) != 0 ? 3 : 2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read a Fast-Path packet header.\n
|
||||
* @param s stream
|
||||
* @param encryptionFlags
|
||||
* @return length
|
||||
*/
|
||||
UINT16 fastpath_read_header(rdpFastPath* fastpath, wStream* s)
|
||||
{
|
||||
BYTE header;
|
||||
UINT16 length;
|
||||
|
||||
if (!s || (Stream_GetRemainingLength(s) < 1))
|
||||
return 0;
|
||||
|
||||
Stream_Read_UINT8(s, header);
|
||||
|
||||
if (fastpath)
|
||||
{
|
||||
fastpath->encryptionFlags = (header & 0xC0) >> 6;
|
||||
fastpath->numberEvents = (header & 0x3C) >> 2;
|
||||
}
|
||||
|
||||
if (!per_read_length(s, &length))
|
||||
return 0;
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
static BOOL fastpath_read_update_header(wStream* s, BYTE* updateCode, BYTE* fragmentation,
|
||||
BYTE* compression)
|
||||
{
|
||||
|
@ -172,9 +137,7 @@ static BOOL fastpath_write_update_header(wStream* s, FASTPATH_UPDATE_HEADER* fpU
|
|||
|
||||
static UINT32 fastpath_get_update_header_size(FASTPATH_UPDATE_HEADER* fpUpdateHeader)
|
||||
{
|
||||
if (!fpUpdateHeader)
|
||||
return 0;
|
||||
|
||||
WINPR_ASSERT(fpUpdateHeader);
|
||||
return (fpUpdateHeader->compression) ? 4 : 3;
|
||||
}
|
||||
|
||||
|
@ -197,6 +160,7 @@ static BOOL fastpath_write_update_pdu_header(wStream* s,
|
|||
|
||||
if (fpUpdatePduHeader->secFlags)
|
||||
{
|
||||
WINPR_ASSERT(rdp->settings);
|
||||
if (rdp->settings->EncryptionMethods == ENCRYPTION_METHOD_FIPS)
|
||||
{
|
||||
if (Stream_GetRemainingCapacity(s) < 4)
|
||||
|
@ -226,6 +190,7 @@ static UINT32 fastpath_get_update_pdu_header_size(FASTPATH_UPDATE_PDU_HEADER* fp
|
|||
{
|
||||
size += 8; /* dataSignature */
|
||||
|
||||
WINPR_ASSERT(rdp->settings);
|
||||
if (rdp->settings->EncryptionMethods == ENCRYPTION_METHOD_FIPS)
|
||||
size += 4; /* fipsInformation */
|
||||
}
|
||||
|
@ -354,6 +319,9 @@ static BOOL fastpath_recv_update_synchronize(rdpFastPath* fastpath, wStream* s)
|
|||
{
|
||||
/* server 2008 can send invalid synchronize packet with missing padding,
|
||||
so don't return FALSE even if the packet is invalid */
|
||||
WINPR_ASSERT(fastpath);
|
||||
WINPR_ASSERT(s);
|
||||
|
||||
Stream_SafeSeek(s, 2); /* size (2 bytes), MUST be set to zero */
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -375,7 +343,11 @@ static int fastpath_recv_update(rdpFastPath* fastpath, BYTE updateCode, wStream*
|
|||
return -1;
|
||||
|
||||
context = update->context;
|
||||
WINPR_ASSERT(context);
|
||||
|
||||
pointer = update->pointer;
|
||||
WINPR_ASSERT(pointer);
|
||||
|
||||
#ifdef WITH_DEBUG_RDP
|
||||
DEBUG_RDP("recv Fast-Path %s Update (0x%02" PRIX8 "), length:%" PRIuz "",
|
||||
fastpath_update_to_string(updateCode), updateCode, Stream_GetRemainingLength(s));
|
||||
|
@ -517,7 +489,7 @@ static int fastpath_recv_update_data(rdpFastPath* fastpath, wStream* s)
|
|||
if (!rdp)
|
||||
return -1;
|
||||
|
||||
transport = fastpath->rdp->transport;
|
||||
transport = rdp->transport;
|
||||
|
||||
if (!transport)
|
||||
return -1;
|
||||
|
@ -584,6 +556,7 @@ static int fastpath_recv_update_data(rdpFastPath* fastpath, wStream* s)
|
|||
{
|
||||
const size_t totalSize = Stream_GetPosition(fastpath->updateData);
|
||||
|
||||
WINPR_ASSERT(transport->settings);
|
||||
if (totalSize > transport->settings->MultifragMaxRequestSize)
|
||||
{
|
||||
WLog_ERR(TAG, "Total size (%" PRIuz ") exceeds MultifragMaxRequestSize (%" PRIu32 ")",
|
||||
|
@ -791,6 +764,9 @@ static BOOL fastpath_recv_input_event_unicode(rdpFastPath* fastpath, wStream* s,
|
|||
else
|
||||
flags |= KBD_FLAGS_DOWN;
|
||||
|
||||
WINPR_ASSERT(fastpath->rdp);
|
||||
WINPR_ASSERT(fastpath->rdp);
|
||||
WINPR_ASSERT(fastpath->rdp->input);
|
||||
return IFCALLRESULT(FALSE, fastpath->rdp->input->UnicodeKeyboardEvent, fastpath->rdp->input,
|
||||
flags, unicodeCode);
|
||||
}
|
||||
|
@ -948,6 +924,8 @@ BOOL fastpath_send_multiple_input_pdu(rdpFastPath* fastpath, wStream* s, size_t
|
|||
goto fail;
|
||||
|
||||
rdp = fastpath->rdp;
|
||||
WINPR_ASSERT(rdp);
|
||||
|
||||
state = rdp_get_state(rdp);
|
||||
if (state != CONNECTION_STATE_ACTIVE)
|
||||
{
|
||||
|
@ -991,6 +969,7 @@ BOOL fastpath_send_multiple_input_pdu(rdpFastPath* fastpath, wStream* s, size_t
|
|||
BYTE* fpInputEvents = Stream_Pointer(s) + sec_bytes;
|
||||
UINT16 fpInputEvents_length = length - 3 - sec_bytes;
|
||||
|
||||
WINPR_ASSERT(rdp->settings);
|
||||
if (rdp->settings->EncryptionMethods == ENCRYPTION_METHOD_FIPS)
|
||||
{
|
||||
BYTE pad;
|
||||
|
@ -1042,7 +1021,7 @@ BOOL fastpath_send_multiple_input_pdu(rdpFastPath* fastpath, wStream* s, size_t
|
|||
Stream_SetPosition(s, length);
|
||||
Stream_SealLength(s);
|
||||
|
||||
if (transport_write(fastpath->rdp->transport, s) < 0)
|
||||
if (transport_write(rdp->transport, s) < 0)
|
||||
goto fail;
|
||||
|
||||
rc = TRUE;
|
||||
|
@ -1258,6 +1237,9 @@ BOOL fastpath_send_update_pdu(rdpFastPath* fastpath, BYTE updateCode, wStream* s
|
|||
rdpFastPath* fastpath_new(rdpRdp* rdp)
|
||||
{
|
||||
rdpFastPath* fastpath;
|
||||
|
||||
WINPR_ASSERT(rdp);
|
||||
|
||||
fastpath = (rdpFastPath*)calloc(1, sizeof(rdpFastPath));
|
||||
|
||||
if (!fastpath)
|
||||
|
@ -1286,3 +1268,9 @@ void fastpath_free(rdpFastPath* fastpath)
|
|||
free(fastpath);
|
||||
}
|
||||
}
|
||||
|
||||
BYTE fastpath_get_encryption_flags(rdpFastPath* fastpath)
|
||||
{
|
||||
WINPR_ASSERT(fastpath);
|
||||
return fastpath->encryptionFlags;
|
||||
}
|
||||
|
|
|
@ -140,18 +140,6 @@ struct _FASTPATH_UPDATE_HEADER
|
|||
};
|
||||
typedef struct _FASTPATH_UPDATE_HEADER FASTPATH_UPDATE_HEADER;
|
||||
|
||||
struct rdp_fastpath
|
||||
{
|
||||
rdpRdp* rdp;
|
||||
wStream* fs;
|
||||
BYTE encryptionFlags;
|
||||
BYTE numberEvents;
|
||||
wStream* updateData;
|
||||
int fragmentation;
|
||||
};
|
||||
|
||||
FREERDP_LOCAL UINT16 fastpath_header_length(wStream* s);
|
||||
FREERDP_LOCAL UINT16 fastpath_read_header(rdpFastPath* fastpath, wStream* s);
|
||||
FREERDP_LOCAL BOOL fastpath_read_header_rdp(rdpFastPath* fastpath, wStream* s, UINT16* length);
|
||||
FREERDP_LOCAL int fastpath_recv_updates(rdpFastPath* fastpath, wStream* s);
|
||||
FREERDP_LOCAL int fastpath_recv_inputs(rdpFastPath* fastpath, wStream* s);
|
||||
|
@ -170,6 +158,7 @@ FREERDP_LOCAL BOOL fastpath_send_update_pdu(rdpFastPath* fastpath, BYTE updateCo
|
|||
|
||||
FREERDP_LOCAL BOOL fastpath_send_surfcmd_frame_marker(rdpFastPath* fastpath, UINT16 frameAction,
|
||||
UINT32 frameId);
|
||||
FREERDP_LOCAL BYTE fastpath_get_encryption_flags(rdpFastPath* fastpath);
|
||||
|
||||
FREERDP_LOCAL rdpFastPath* fastpath_new(rdpRdp* rdp);
|
||||
FREERDP_LOCAL void fastpath_free(rdpFastPath* fastpath);
|
||||
|
|
|
@ -525,10 +525,10 @@ static int peer_recv_fastpath_pdu(freerdp_peer* client, wStream* s)
|
|||
return -1;
|
||||
}
|
||||
|
||||
if (fastpath->encryptionFlags & FASTPATH_OUTPUT_ENCRYPTED)
|
||||
if (fastpath_get_encryption_flags(fastpath) & FASTPATH_OUTPUT_ENCRYPTED)
|
||||
{
|
||||
if (!rdp_decrypt(rdp, s, &length,
|
||||
(fastpath->encryptionFlags & FASTPATH_OUTPUT_SECURE_CHECKSUM)
|
||||
(fastpath_get_encryption_flags(fastpath) & FASTPATH_OUTPUT_SECURE_CHECKSUM)
|
||||
? SEC_SECURE_CHECKSUM
|
||||
: 0))
|
||||
return -1;
|
||||
|
|
|
@ -1472,10 +1472,11 @@ static int rdp_recv_fastpath_pdu(rdpRdp* rdp, wStream* s)
|
|||
rdp->autodetect->bandwidthMeasureByteCount += length;
|
||||
}
|
||||
|
||||
if (fastpath->encryptionFlags & FASTPATH_OUTPUT_ENCRYPTED)
|
||||
if (fastpath_get_encryption_flags(fastpath) & FASTPATH_OUTPUT_ENCRYPTED)
|
||||
{
|
||||
UINT16 flags =
|
||||
(fastpath->encryptionFlags & FASTPATH_OUTPUT_SECURE_CHECKSUM) ? SEC_SECURE_CHECKSUM : 0;
|
||||
UINT16 flags = (fastpath_get_encryption_flags(fastpath) & FASTPATH_OUTPUT_SECURE_CHECKSUM)
|
||||
? SEC_SECURE_CHECKSUM
|
||||
: 0;
|
||||
|
||||
if (!rdp_decrypt(rdp, s, &length, flags))
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue