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 int APP_CC
xrdp_sec_init(struct xrdp_sec* self, struct stream* s); xrdp_sec_init(struct xrdp_sec* self, struct stream* s);
int APP_CC 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); xrdp_sec_init_fastpath(struct xrdp_sec *self, struct stream *s);
int APP_CC int APP_CC
xrdp_sec_send_fastpath(struct xrdp_sec *self, struct stream *s); 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; 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 */ /* FASTPATH_INPUT_EVENT_SCANCODE */
int APP_CC 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 flags;
int code; int code;
@ -284,9 +134,13 @@ xrdp_fastpath_process_EVENT_SCANCODE(struct xrdp_fastpath *self, int eventFlags,
in_uint8(s, code); /* keyCode (1 byte) */ in_uint8(s, code); /* keyCode (1 byte) */
if ((eventFlags & FASTPATH_INPUT_KBDFLAGS_RELEASE)) if ((eventFlags & FASTPATH_INPUT_KBDFLAGS_RELEASE))
{
flags |= KBD_FLAG_UP; flags |= KBD_FLAG_UP;
}
else else
{
flags |= KBD_FLAG_DOWN; flags |= KBD_FLAG_DOWN;
}
if ((eventFlags & FASTPATH_INPUT_KBDFLAGS_EXTENDED)) if ((eventFlags & FASTPATH_INPUT_KBDFLAGS_EXTENDED))
flags |= KBD_FLAG_EXT; flags |= KBD_FLAG_EXT;
@ -372,11 +226,14 @@ xrdp_fastpath_process_EVENT_MOUSEX(struct xrdp_fastpath *self,
/*****************************************************************************/ /*****************************************************************************/
/* FASTPATH_INPUT_EVENT_SYNC */ /* FASTPATH_INPUT_EVENT_SYNC */
int APP_CC 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 eventCode bitfield (3 bits in size) MUST be set to
* The eventFlags bitfield (5 bits in size) contains flags indicating the "on" * FASTPATH_INPUT_EVENT_SYNC (3).
* The eventFlags bitfield (5 bits in size) contains flags
* indicating the "on"
* status of the keyboard toggle keys. * status of the keyboard toggle keys.
*/ */
if (self->session->callback != 0) if (self->session->callback != 0)
@ -417,7 +274,7 @@ xrdp_fastpath_process_input_event(struct xrdp_fastpath *self, struct stream *s)
int eventCode; int eventCode;
int eventFlags; int eventFlags;
// process fastpath input events /* process fastpath input events */
for (i = 0; i < self->numEvents; i++) for (i = 0; i < self->numEvents; i++)
{ {
if (!s_check_rem(s, 1)) 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); eventFlags = (eventHeader & 0x1F);
eventCode = (eventHeader >> 5); 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) switch (eventCode)
{ {
case FASTPATH_INPUT_EVENT_SCANCODE: 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; return 1;
} }
break; break;
case FASTPATH_INPUT_EVENT_MOUSE: 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; return 1;
} }
break; break;
case FASTPATH_INPUT_EVENT_MOUSEX: 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; return 1;
} }
break; break;
case FASTPATH_INPUT_EVENT_SYNC: 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; return 1;
} }
break; break;
case FASTPATH_INPUT_EVENT_UNICODE: 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; return 1;
} }
break; break;
default: default:
g_writeln("xrdp_fastpath_process_input_event: unknown eventCode %d", eventCode); g_writeln("xrdp_fastpath_process_input_event: unknown "
"eventCode %d", eventCode);
break; break;
} }
} }

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

@ -32,6 +32,8 @@
#define LLOGLN(_level, _args) \ #define LLOGLN(_level, _args) \
do { if (_level < LOG_LEVEL) { g_writeln _args ; } } while (0) do { if (_level < LOG_LEVEL) { g_writeln _args ; } } while (0)
#define FASTPATH_FRAG_SIZE (16 * 1024 + 1024)
/*****************************************************************************/ /*****************************************************************************/
static int APP_CC static int APP_CC
xrdp_rdp_read_config(struct xrdp_client_info *client_info) 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 */ /* 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 int APP_CC
xrdp_rdp_send_fastpath(struct xrdp_rdp *self, struct stream *s, xrdp_rdp_send_fastpath(struct xrdp_rdp *self, struct stream *s,
int data_pdu_type) int data_pdu_type)
{ {
int updateHeader; int updateHeader;
int updateCode;
int fragmentation;
int compression;
int ctype; int ctype;
int len; int len;
int cont;
int header_bytes;
int sec_bytes;
struct stream ls;
char *holdp;
char *holdend;
LLOGLN(10, ("xrdp_rdp_send_fastpath:")); LLOGLN(10, ("xrdp_rdp_send_fastpath:"));
s_pop_layer(s, rdp_hdr); s_pop_layer(s, rdp_hdr);
len = (int)(s->end - s->p); updateCode = data_pdu_type;
if (self->client_info.rdp_compression) if (self->client_info.rdp_compression)
{ {
/* TODO: finish compression */ compression = 2;
LLOGLN(10, ("xrdp_rdp_send_fastpath: compress")); header_bytes = 4;
updateHeader = data_pdu_type & 15;
updateHeader |= 2 << 6; /* FASTPATH_OUTPUT_COMPRESSION_USED */
out_uint8(s, updateHeader);
ctype = 0;
out_uint8(s, ctype);
len -= 4;
} }
else else
{ {
LLOGLN(10, ("xrdp_rdp_send_fastpath: no compress")); compression = 0;
updateHeader = data_pdu_type & 15; header_bytes = 3;
out_uint8(s, updateHeader);
len -= 3;
} }
out_uint16_le(s, len); sec_bytes = xrdp_sec_get_fastpath_bytes(self->sec_layer);
if (xrdp_sec_send_fastpath(self->sec_layer, s) != 0) fragmentation = 0;
ls = *s;
cont = 1;
while (cont)
{ {
LLOGLN(0, ("xrdp_rdp_send_fastpath: xrdp_fastpath_send failed")); len = (int)(ls.end - ls.p);
return 1; 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; return 0;
} }

@ -1246,6 +1246,22 @@ xrdp_sec_send(struct xrdp_sec *self, struct stream *s, int chan)
return 0; 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 */ /* returns error */
int APP_CC int APP_CC
@ -1272,6 +1288,8 @@ xrdp_sec_init_fastpath(struct xrdp_sec *self, struct stream *s)
/*****************************************************************************/ /*****************************************************************************/
/* returns error */ /* 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 int APP_CC
xrdp_sec_send_fastpath(struct xrdp_sec *self, struct stream *s) 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_be(s, pdulen);
out_uint16_le(s, 16); /* crypto header size */ out_uint16_le(s, 16); /* crypto header size */
out_uint8(s, 1); /* fips version */ out_uint8(s, 1); /* fips version */
g_memset(s->end, 0, pad);
s->end += pad; s->end += pad;
out_uint8(s, pad); /* fips pad */ out_uint8(s, pad); /* fips pad */
xrdp_sec_fips_sign(self, s->p, 8, s->p + 8, datalen); xrdp_sec_fips_sign(self, s->p, 8, s->p + 8, datalen);

Loading…
Cancel
Save