libxrdp: work on fastpath fragments

ulab-next
Jay Sorg 11 years ago
parent ac6717e32e
commit d18704d740

@ -346,6 +346,8 @@ xrdp_sec_delete(struct xrdp_sec* self);
int APP_CC
xrdp_sec_init(struct xrdp_sec* self, struct stream* s);
int APP_CC
xrdp_sec_get_fastpath_bytes(struct xrdp_sec *self);
int APP_CC
xrdp_sec_init_fastpath(struct xrdp_sec *self, struct stream *s);
int APP_CC
xrdp_sec_send_fastpath(struct xrdp_sec *self, struct stream *s);

@ -117,161 +117,11 @@ xrdp_fastpath_send(struct xrdp_fastpath *self, struct stream *s)
return 0;
}
#if 0
/*****************************************************************************/
int APP_CC
xrdp_fastpath_send_update_pdu(struct xrdp_fastpath *self, tui8 updateCode,
struct stream *s)
{
tui16 len;
tui16 maxLen;
tui32 payloadLeft;
tui8 fragment;
struct stream *s_send;
int compression;
int i;
int i32;
compression = 0;
// s_send = self->out_s;
maxLen = FASTPATH_MAX_PACKET_SIZE - 6; /* 6 bytes for header */
payloadLeft = (s->end - s->data);
for (i = 0; payloadLeft > 0; i++)
{
if (payloadLeft > maxLen)
{
len = maxLen;
}
else
{
len = payloadLeft;
}
payloadLeft -= len;
if (payloadLeft == 0)
{
fragment = i ? FASTPATH_FRAGMENT_LAST : FASTPATH_FRAGMENT_SINGLE;
}
else
{
fragment = i ? FASTPATH_FRAGMENT_NEXT : FASTPATH_FRAGMENT_FIRST;
}
init_stream(s_send, 0);
out_uint8(s_send, 0); /* fOutputHeader */
i32 = ((len + 6) >> 8) | 0x80;
out_uint8(s_send, i32); /* use 2 bytes for length even length < 128 ??? */
i32 = (len + 6) & 0xff;
out_uint8(s_send, i32);
i32 = (updateCode & 0x0f) | ((fragment & 0x03) << 4) |
((compression & 0x03) << 6);
out_uint8(s_send, i32);
out_uint16_le(s_send, len);
// s_copy(s_send, s, len);
s_mark_end(s_send);
// if (xrdp_tcp_send(self->tcp_layer, s_send) != 0)
// {
// return 1;
// }
}
return 0;
}
#endif
/*****************************************************************************/
int
xrdp_fastpath_process_update(struct xrdp_fastpath *self, tui8 updateCode,
tui32 size, struct stream *s)
{
switch (updateCode)
{
case FASTPATH_UPDATETYPE_ORDERS:
case FASTPATH_UPDATETYPE_BITMAP:
case FASTPATH_UPDATETYPE_PALETTE:
case FASTPATH_UPDATETYPE_SYNCHRONIZE:
case FASTPATH_UPDATETYPE_SURFCMDS:
case FASTPATH_UPDATETYPE_PTR_NULL:
case FASTPATH_UPDATETYPE_PTR_DEFAULT:
case FASTPATH_UPDATETYPE_PTR_POSITION:
case FASTPATH_UPDATETYPE_COLOR:
case FASTPATH_UPDATETYPE_CACHED:
case FASTPATH_UPDATETYPE_POINTER:
break;
default:
g_writeln("xrdp_fastpath_process_update: unknown updateCode 0x%X",
updateCode);
break;
}
return 0;
}
#if 0
/*****************************************************************************/
int APP_CC
xrdp_fastpath_process_data(struct xrdp_fastpath *self, struct stream *s,
tui8 header)
{
tui8 encryptionFlags;
tui8 numberEvents;
tui8 length2;
tui8 updateHeader;
tui8 updateCode;
tui8 updateFrag;
tui8 updateComp;
tui16 length;
tui32 size;
encryptionFlags = (header & 0xc0) >> 6;
numberEvents = (header & 0x3c) >> 2;
// xrdp_tcp_recv(self->tcp_layer, s, 1);
in_uint8(s, length);
if (length & 0x80)
{
// xrdp_tcp_recv(self->tcp_layer, s, 1);
in_uint8(s, length2);
length = (length & 0x7f) << 8 + length2 - 3;
}
else
{
length -= 2;
}
// xrdp_tcp_recv(self->tcp_layer, s, length);
if (encryptionFlags != 0)
{
/* TODO decryption ...*/
}
/* parse updateHeader */
in_uint8(s, updateHeader);
updateCode = (updateHeader & 0x0f);
updateFrag = (updateHeader & 0x30) >> 4;
updateComp = (updateHeader & 0xc0) >> 6;
if (updateFrag && updateComp)
{
/* TODO */
g_writeln("xrdp_fastpath_process_data: updateFrag=%d, updateComp=%d",
updateFrag, updateComp);
return 1;
}
in_uint16_le(s, size);
return xrdp_fastpath_process_update(self, updateCode, size, s);
}
#endif
/*****************************************************************************/
/* FASTPATH_INPUT_EVENT_SCANCODE */
int APP_CC
xrdp_fastpath_process_EVENT_SCANCODE(struct xrdp_fastpath *self, int eventFlags, struct stream *s)
xrdp_fastpath_process_EVENT_SCANCODE(struct xrdp_fastpath *self,
int eventFlags, struct stream *s)
{
int flags;
int code;
@ -284,9 +134,13 @@ xrdp_fastpath_process_EVENT_SCANCODE(struct xrdp_fastpath *self, int eventFlags,
in_uint8(s, code); /* keyCode (1 byte) */
if ((eventFlags & FASTPATH_INPUT_KBDFLAGS_RELEASE))
{
flags |= KBD_FLAG_UP;
}
else
{
flags |= KBD_FLAG_DOWN;
}
if ((eventFlags & FASTPATH_INPUT_KBDFLAGS_EXTENDED))
flags |= KBD_FLAG_EXT;
@ -372,11 +226,14 @@ xrdp_fastpath_process_EVENT_MOUSEX(struct xrdp_fastpath *self,
/*****************************************************************************/
/* FASTPATH_INPUT_EVENT_SYNC */
int APP_CC
xrdp_fastpath_process_EVENT_SYNC(struct xrdp_fastpath *self, int eventCode, int eventFlags, struct stream *s)
xrdp_fastpath_process_EVENT_SYNC(struct xrdp_fastpath *self, int eventCode,
int eventFlags, struct stream *s)
{
/*
* The eventCode bitfield (3 bits in size) MUST be set to FASTPATH_INPUT_EVENT_SYNC (3).
* The eventFlags bitfield (5 bits in size) contains flags indicating the "on"
* The eventCode bitfield (3 bits in size) MUST be set to
* FASTPATH_INPUT_EVENT_SYNC (3).
* The eventFlags bitfield (5 bits in size) contains flags
* indicating the "on"
* status of the keyboard toggle keys.
*/
if (self->session->callback != 0)
@ -417,7 +274,7 @@ xrdp_fastpath_process_input_event(struct xrdp_fastpath *self, struct stream *s)
int eventCode;
int eventFlags;
// process fastpath input events
/* process fastpath input events */
for (i = 0; i < self->numEvents; i++)
{
if (!s_check_rem(s, 1))
@ -429,44 +286,52 @@ xrdp_fastpath_process_input_event(struct xrdp_fastpath *self, struct stream *s)
eventFlags = (eventHeader & 0x1F);
eventCode = (eventHeader >> 5);
//DEBUG(("xrdp_fastpath_process_input_event: eventCode= %d, eventFlags= %d, numEvents= %d",
// eventCode, eventFlags, self->sec_layer->fastpath_layer->numEvents));
switch (eventCode)
{
case FASTPATH_INPUT_EVENT_SCANCODE:
if (xrdp_fastpath_process_EVENT_SCANCODE(self, eventFlags, s) != 0)
if (xrdp_fastpath_process_EVENT_SCANCODE(self,
eventFlags,
s) != 0)
{
return 1;
}
break;
case FASTPATH_INPUT_EVENT_MOUSE:
if (xrdp_fastpath_process_EVENT_MOUSE(self, eventFlags, s) != 0)
if (xrdp_fastpath_process_EVENT_MOUSE(self,
eventFlags,
s) != 0)
{
return 1;
}
break;
case FASTPATH_INPUT_EVENT_MOUSEX:
if (xrdp_fastpath_process_EVENT_MOUSEX(self, eventFlags, s) != 0)
if (xrdp_fastpath_process_EVENT_MOUSEX(self,
eventFlags,
s) != 0)
{
return 1;
}
break;
case FASTPATH_INPUT_EVENT_SYNC:
if (xrdp_fastpath_process_EVENT_SYNC(self, eventCode, eventFlags, s) != 0)
if (xrdp_fastpath_process_EVENT_SYNC(self, eventCode,
eventFlags,
s) != 0)
{
return 1;
}
break;
case FASTPATH_INPUT_EVENT_UNICODE:
if (xrdp_fastpath_process_EVENT_UNICODE(self, eventFlags, s) != 0)
if (xrdp_fastpath_process_EVENT_UNICODE(self,
eventFlags,
s) != 0)
{
return 1;
}
break;
default:
g_writeln("xrdp_fastpath_process_input_event: unknown eventCode %d", eventCode);
g_writeln("xrdp_fastpath_process_input_event: unknown "
"eventCode %d", eventCode);
break;
}
}

@ -34,6 +34,8 @@
} \
}
#define MAX_ORDERS_SIZE (16 * 1024 + 512)
/*****************************************************************************/
struct xrdp_orders *APP_CC
xrdp_orders_create(struct xrdp_session *session, struct xrdp_rdp *rdp_layer)
@ -44,7 +46,7 @@ xrdp_orders_create(struct xrdp_session *session, struct xrdp_rdp *rdp_layer)
self->session = session;
self->rdp_layer = rdp_layer;
make_stream(self->out_s);
init_stream(self->out_s, 16384);
init_stream(self->out_s, 32 * 1024);
self->orders_state.clip_right = 1; /* silly rdp right clip */
self->orders_state.clip_bottom = 1; /* silly rdp bottom clip */
self->jpeg_han = xrdp_jpeg_init();
@ -212,14 +214,7 @@ xrdp_orders_check(struct xrdp_orders *self, int max_size)
int size;
int max_packet_size;
if (self->rdp_layer->client_info.bpp == 8)
{
max_packet_size = 8000;
}
else
{
max_packet_size = 16000;
}
max_packet_size = MAX_ORDERS_SIZE;
if (self->order_level < 1)
{

@ -32,6 +32,8 @@
#define LLOGLN(_level, _args) \
do { if (_level < LOG_LEVEL) { g_writeln _args ; } } while (0)
#define FASTPATH_FRAG_SIZE (16 * 1024 + 1024)
/*****************************************************************************/
static int APP_CC
xrdp_rdp_read_config(struct xrdp_client_info *client_info)
@ -526,40 +528,94 @@ xrdp_rdp_init_fastpath(struct xrdp_rdp *self, struct stream *s)
/*****************************************************************************/
/* TODO: compression */
/* returns error */
/* 2.2.9.1.2.1 Fast-Path Update (TS_FP_UPDATE)
* http://msdn.microsoft.com/en-us/library/cc240622.aspx */
int APP_CC
xrdp_rdp_send_fastpath(struct xrdp_rdp *self, struct stream *s,
int data_pdu_type)
{
int updateHeader;
int updateCode;
int fragmentation;
int compression;
int ctype;
int len;
int cont;
int header_bytes;
int sec_bytes;
struct stream ls;
char *holdp;
char *holdend;
LLOGLN(10, ("xrdp_rdp_send_fastpath:"));
s_pop_layer(s, rdp_hdr);
len = (int)(s->end - s->p);
updateCode = data_pdu_type;
if (self->client_info.rdp_compression)
{
/* TODO: finish compression */
LLOGLN(10, ("xrdp_rdp_send_fastpath: compress"));
updateHeader = data_pdu_type & 15;
updateHeader |= 2 << 6; /* FASTPATH_OUTPUT_COMPRESSION_USED */
out_uint8(s, updateHeader);
ctype = 0;
out_uint8(s, ctype);
len -= 4;
compression = 2;
header_bytes = 4;
}
else
{
LLOGLN(10, ("xrdp_rdp_send_fastpath: no compress"));
updateHeader = data_pdu_type & 15;
out_uint8(s, updateHeader);
len -= 3;
compression = 0;
header_bytes = 3;
}
out_uint16_le(s, len);
if (xrdp_sec_send_fastpath(self->sec_layer, s) != 0)
sec_bytes = xrdp_sec_get_fastpath_bytes(self->sec_layer);
fragmentation = 0;
ls = *s;
cont = 1;
while (cont)
{
LLOGLN(0, ("xrdp_rdp_send_fastpath: xrdp_fastpath_send failed"));
return 1;
len = (int)(ls.end - ls.p);
if (len > FASTPATH_FRAG_SIZE)
{
len = FASTPATH_FRAG_SIZE;
if (fragmentation == 0)
{
fragmentation = 2; /* FASTPATH_FRAGMENT_FIRST */
}
else if (fragmentation == 2)
{
fragmentation = 3; /* FASTPATH_FRAGMENT_NEXT */
}
}
else
{
if (fragmentation != 0)
{
fragmentation = 1; /* FASTPATH_FRAGMENT_LAST */
}
}
len = MIN(len, 32 * 1024);
LLOGLN(10, ("xrdp_rdp_send_fastpath: len %d fragmentation %d",
len, fragmentation));
updateHeader = (updateCode & 15) |
((fragmentation & 3) << 4) |
((compression & 3) << 6);
out_uint8(&ls, updateHeader);
if (compression != 0)
{
/* TODO: */
ctype = 0;
out_uint8(&ls, ctype);
}
len -= header_bytes;
out_uint16_le(&ls, len);
holdp = ls.p;
holdend = ls.end;
ls.end = ls.p + len;
if (xrdp_sec_send_fastpath(self->sec_layer, &ls) != 0)
{
LLOGLN(0, ("xrdp_rdp_send_fastpath: xrdp_fastpath_send failed"));
return 1;
}
ls.p = holdp + len;
ls.end = holdend;
cont = ls.p < ls.end;
ls.p -= header_bytes;
ls.sec_hdr = ls.p - sec_bytes;
ls.data = ls.sec_hdr;
}
return 0;
}

@ -1246,6 +1246,22 @@ xrdp_sec_send(struct xrdp_sec *self, struct stream *s, int chan)
return 0;
}
/*****************************************************************************/
/* returns the fastpath sec byte count */
int APP_CC
xrdp_sec_get_fastpath_bytes(struct xrdp_sec *self)
{
if (self->crypt_level == CRYPT_LEVEL_FIPS)
{
return 3 + 4 + 8;
}
else if (self->crypt_level > CRYPT_LEVEL_LOW)
{
return 3 + 8;
}
return 3;
}
/*****************************************************************************/
/* returns error */
int APP_CC
@ -1272,6 +1288,8 @@ xrdp_sec_init_fastpath(struct xrdp_sec *self, struct stream *s)
/*****************************************************************************/
/* returns error */
/* 2.2.9.1.2 Server Fast-Path Update PDU (TS_FP_UPDATE_PDU)
* http://msdn.microsoft.com/en-us/library/cc240621.aspx */
int APP_CC
xrdp_sec_send_fastpath(struct xrdp_sec *self, struct stream *s)
{
@ -1297,7 +1315,6 @@ xrdp_sec_send_fastpath(struct xrdp_sec *self, struct stream *s)
out_uint16_be(s, pdulen);
out_uint16_le(s, 16); /* crypto header size */
out_uint8(s, 1); /* fips version */
g_memset(s->end, 0, pad);
s->end += pad;
out_uint8(s, pad); /* fips pad */
xrdp_sec_fips_sign(self, s->p, 8, s->p + 8, datalen);

Loading…
Cancel
Save