summaryrefslogtreecommitdiffstats
path: root/libxrdp
diff options
context:
space:
mode:
authorJay Sorg <jay.sorg@gmail.com>2014-03-09 12:11:36 -0700
committerJay Sorg <jay.sorg@gmail.com>2014-03-09 12:11:36 -0700
commitd18704d74060e41f45e7b772544d375fdf80099c (patch)
treec98cb3fc1e3c16d464d3781d7af0b7aec6290885 /libxrdp
parentac6717e32e16c057bfb7d5c75b96d83c5618b6e0 (diff)
downloadxrdp-proprietary-d18704d74060e41f45e7b772544d375fdf80099c.tar.gz
xrdp-proprietary-d18704d74060e41f45e7b772544d375fdf80099c.zip
libxrdp: work on fastpath fragments
Diffstat (limited to 'libxrdp')
-rw-r--r--libxrdp/libxrdp.h2
-rw-r--r--libxrdp/xrdp_fastpath.c195
-rw-r--r--libxrdp/xrdp_orders.c13
-rw-r--r--libxrdp/xrdp_rdp.c90
-rw-r--r--libxrdp/xrdp_sec.c19
5 files changed, 127 insertions, 192 deletions
diff --git a/libxrdp/libxrdp.h b/libxrdp/libxrdp.h
index da8ebc3f..39e36d4b 100644
--- a/libxrdp/libxrdp.h
+++ b/libxrdp/libxrdp.h
@@ -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);
diff --git a/libxrdp/xrdp_fastpath.c b/libxrdp/xrdp_fastpath.c
index 681d5424..27877ef1 100644
--- a/libxrdp/xrdp_fastpath.c
+++ b/libxrdp/xrdp_fastpath.c
@@ -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;
}
}
diff --git a/libxrdp/xrdp_orders.c b/libxrdp/xrdp_orders.c
index 819c3d06..fd96e2a4 100644
--- a/libxrdp/xrdp_orders.c
+++ b/libxrdp/xrdp_orders.c
@@ -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)
{
diff --git a/libxrdp/xrdp_rdp.c b/libxrdp/xrdp_rdp.c
index 43daa874..86a4f7bf 100644
--- a/libxrdp/xrdp_rdp.c
+++ b/libxrdp/xrdp_rdp.c
@@ -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;
}
diff --git a/libxrdp/xrdp_sec.c b/libxrdp/xrdp_sec.c
index 15c784d8..5e4e8800 100644
--- a/libxrdp/xrdp_sec.c
+++ b/libxrdp/xrdp_sec.c
@@ -1247,6 +1247,22 @@ xrdp_sec_send(struct xrdp_sec *self, struct stream *s, int chan)
}
/*****************************************************************************/
+/* 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
xrdp_sec_init_fastpath(struct xrdp_sec *self, struct stream *s)
@@ -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);