libxrdp: fastpath output, orders working

ulab-next
Jay Sorg 11 years ago
parent cf39a90d80
commit ff8821c308

@ -346,6 +346,10 @@ 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_init_fastpath(struct xrdp_sec *self, struct stream *s);
int APP_CC
xrdp_sec_send_fastpath(struct xrdp_sec *self, struct stream *s);
int APP_CC
xrdp_sec_recv_fastpath(struct xrdp_sec *self, struct stream *s);
int APP_CC
xrdp_sec_recv(struct xrdp_sec* self, struct stream* s, int* chan);
@ -370,6 +374,8 @@ xrdp_rdp_init(struct xrdp_rdp* self, struct stream* s);
int APP_CC
xrdp_rdp_init_data(struct xrdp_rdp* self, struct stream* s);
int APP_CC
xrdp_rdp_init_fastpath(struct xrdp_rdp *self, struct stream *s);
int APP_CC
xrdp_rdp_recv(struct xrdp_rdp* self, struct stream* s, int* code);
int APP_CC
xrdp_rdp_send(struct xrdp_rdp* self, struct stream* s, int pdu_type);
@ -377,6 +383,9 @@ int APP_CC
xrdp_rdp_send_data(struct xrdp_rdp* self, struct stream* s,
int data_pdu_type);
int APP_CC
xrdp_rdp_send_fastpath(struct xrdp_rdp *self, struct stream *s,
int data_pdu_type);
int APP_CC
xrdp_rdp_send_data_update_sync(struct xrdp_rdp* self);
int APP_CC
xrdp_rdp_incoming(struct xrdp_rdp* self);
@ -554,4 +563,9 @@ int APP_CC
xrdp_fastpath_recv(struct xrdp_fastpath *self, struct stream *s);
int APP_CC
xrdp_fastpath_process_input_event(struct xrdp_fastpath *self, struct stream *s);
int APP_CC
xrdp_fastpath_init(struct xrdp_fastpath *self, struct stream *s);
int APP_CC
xrdp_fastpath_send(struct xrdp_fastpath *self, struct stream *s);
#endif

@ -97,12 +97,27 @@ xrdp_fastpath_recv(struct xrdp_fastpath *self, struct stream *s)
}
/*****************************************************************************/
/* no fragmenation */
int APP_CC
xrdp_fastpath_init(struct xrdp_fastpath *self)
xrdp_fastpath_init(struct xrdp_fastpath *self, struct stream *s)
{
init_stream(s, 32 * 1024);
return 0;
}
/*****************************************************************************/
/* no fragmenation */
int APP_CC
xrdp_fastpath_send(struct xrdp_fastpath *self, struct stream *s)
{
if (trans_force_write_s(self->trans, s) != 0)
{
return 1;
}
return 0;
}
#if 0
/*****************************************************************************/
int APP_CC
xrdp_fastpath_send_update_pdu(struct xrdp_fastpath *self, tui8 updateCode,
@ -165,6 +180,7 @@ xrdp_fastpath_send_update_pdu(struct xrdp_fastpath *self, tui8 updateCode,
return 0;
}
#endif
/*****************************************************************************/
int
@ -194,6 +210,7 @@ xrdp_fastpath_process_update(struct xrdp_fastpath *self, tui8 updateCode,
return 0;
}
#if 0
/*****************************************************************************/
int APP_CC
xrdp_fastpath_process_data(struct xrdp_fastpath *self, struct stream *s,
@ -249,6 +266,7 @@ xrdp_fastpath_process_data(struct xrdp_fastpath *self, struct stream *s,
in_uint16_le(s, size);
return xrdp_fastpath_process_update(self, updateCode, size, s);
}
#endif
/*****************************************************************************/
/* FASTPATH_INPUT_EVENT_SCANCODE */

@ -64,7 +64,6 @@ xrdp_orders_delete(struct xrdp_orders *self)
{
return;
}
xrdp_jpeg_deinit(self->jpeg_han);
free_stream(self->out_s);
g_free(self->orders_state.text_data);
@ -81,7 +80,6 @@ xrdp_orders_reset(struct xrdp_orders *self)
{
return 1;
}
g_free(self->orders_state.text_data);
g_memset(&(self->orders_state), 0, sizeof(self->orders_state));
self->order_count_ptr = 0;
@ -98,24 +96,33 @@ int APP_CC
xrdp_orders_init(struct xrdp_orders *self)
{
self->order_level++;
if (self->order_level == 1)
{
self->order_count = 0;
/* is this big enough */
if (self->rdp_layer->client_info.use_fast_path & 1)
{
LLOGLN(10, ("xrdp_orders_init: fastpath"));
if (xrdp_rdp_init_fastpath(self->rdp_layer, self->out_s) != 0)
{
return 1;
}
self->order_count_ptr = self->out_s->p;
out_uint8s(self->out_s, 2); /* number of orders, set later */
}
else
{
LLOGLN(10, ("xrdp_orders_init: slowpath"));
if (xrdp_rdp_init_data(self->rdp_layer, self->out_s) != 0)
{
return 1;
}
out_uint16_le(self->out_s, RDP_UPDATE_ORDERS);
out_uint8s(self->out_s, 2); /* pad */
self->order_count_ptr = self->out_s->p;
out_uint8s(self->out_s, 2); /* number of orders, set later */
out_uint8s(self->out_s, 2); /* pad */
}
}
return 0;
}
@ -127,11 +134,9 @@ xrdp_orders_send(struct xrdp_orders *self)
int rv;
rv = 0;
if (self->order_level > 0)
{
self->order_level--;
if ((self->order_level == 0) && (self->order_count > 0))
{
s_mark_end(self->out_s);
@ -139,7 +144,16 @@ xrdp_orders_send(struct xrdp_orders *self)
self->order_count_ptr[0] = self->order_count;
self->order_count_ptr[1] = self->order_count >> 8;
self->order_count = 0;
if (self->rdp_layer->client_info.use_fast_path & 1)
{
if (xrdp_rdp_send_fastpath(self->rdp_layer,
self->out_s, 0) != 0)
{
rv = 1;
}
}
else
{
if (xrdp_rdp_send_data(self->rdp_layer, self->out_s,
RDP_DATA_PDU_UPDATE) != 0)
{
@ -147,7 +161,7 @@ xrdp_orders_send(struct xrdp_orders *self)
}
}
}
}
return rv;
}
@ -160,21 +174,29 @@ xrdp_orders_force_send(struct xrdp_orders *self)
{
return 1;
}
if ((self->order_level > 0) && (self->order_count > 0))
{
s_mark_end(self->out_s);
DEBUG(("xrdp_orders_force_send sending %d orders", self->order_count));
self->order_count_ptr[0] = self->order_count;
self->order_count_ptr[1] = self->order_count >> 8;
if (self->rdp_layer->client_info.use_fast_path & 1)
{
if (xrdp_rdp_send_fastpath(self->rdp_layer,
self->out_s, 0) != 0)
{
return 1;
}
}
else
{
if (xrdp_rdp_send_data(self->rdp_layer, self->out_s,
RDP_DATA_PDU_UPDATE) != 0)
{
return 1;
}
}
}
self->order_count = 0;
self->order_level = 0;
return 0;

@ -26,6 +26,12 @@
#include <freerdp/constants.h>
#endif
#define LOG_LEVEL 1
#define LLOG(_level, _args) \
do { if (_level < LOG_LEVEL) { g_write _args ; } } while (0)
#define LLOGLN(_level, _args) \
do { if (_level < LOG_LEVEL) { g_writeln _args ; } } while (0)
/*****************************************************************************/
static int APP_CC
xrdp_rdp_read_config(struct xrdp_client_info *client_info)
@ -289,6 +295,7 @@ xrdp_rdp_init_data(struct xrdp_rdp *self, struct stream *s)
s_push_layer(s, rdp_hdr, 18);
return 0;
}
/*****************************************************************************/
/* returns error */
int APP_CC
@ -498,6 +505,65 @@ xrdp_rdp_send_data(struct xrdp_rdp *self, struct stream *s,
return 0;
}
/*****************************************************************************/
int APP_CC
xrdp_rdp_init_fastpath(struct xrdp_rdp *self, struct stream *s)
{
if (xrdp_sec_init_fastpath(self->sec_layer, s) != 0)
{
return 1;
}
if (self->client_info.rdp_compression)
{
s_push_layer(s, rdp_hdr, 4);
}
else
{
s_push_layer(s, rdp_hdr, 3);
}
return 0;
}
/*****************************************************************************/
/* TODO: compression */
int APP_CC
xrdp_rdp_send_fastpath(struct xrdp_rdp *self, struct stream *s,
int data_pdu_type)
{
int updateHeader;
int ctype;
int len;
LLOGLN(10, ("xrdp_rdp_send_fastpath:"));
s_pop_layer(s, rdp_hdr);
len = (int)(s->end - s->p);
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;
}
else
{
LLOGLN(10, ("xrdp_rdp_send_fastpath: no compress"));
updateHeader = data_pdu_type & 15;
out_uint8(s, updateHeader);
len -= 3;
}
out_uint16_le(s, len);
if (xrdp_sec_send_fastpath(self->sec_layer, s) != 0)
{
LLOGLN(0, ("xrdp_rdp_send_fastpath: xrdp_fastpath_send failed"));
return 1;
}
return 0;
}
/*****************************************************************************/
int APP_CC
xrdp_rdp_send_data_update_sync(struct xrdp_rdp *self)
@ -1581,6 +1647,7 @@ xrdp_rdp_send_fontmap(struct xrdp_rdp *self)
free_stream(s);
return 0;
}
/*****************************************************************************/
int APP_CC
xrdp_rdp_send_monitorlayout(struct xrdp_rdp *self)
@ -1620,6 +1687,7 @@ xrdp_rdp_send_monitorlayout(struct xrdp_rdp *self)
free_stream(s);
return 0;
}
/*****************************************************************************/
static int APP_CC
xrdp_rdp_process_data_font(struct xrdp_rdp *self, struct stream *s)

@ -1245,6 +1245,94 @@ xrdp_sec_send(struct xrdp_sec *self, struct stream *s, int chan)
DEBUG((" out xrdp_sec_send"));
return 0;
}
/*****************************************************************************/
/* returns error */
int APP_CC
xrdp_sec_init_fastpath(struct xrdp_sec *self, struct stream *s)
{
if (xrdp_fastpath_init(self->fastpath_layer, s) != 0)
{
return 1;
}
if (self->crypt_level == CRYPT_LEVEL_FIPS)
{
s_push_layer(s, sec_hdr, 3 + 4 + 8);
}
else if (self->crypt_level > CRYPT_LEVEL_LOW)
{
s_push_layer(s, sec_hdr, 3 + 8);
}
else
{
s_push_layer(s, sec_hdr, 3);
}
return 0;
}
/*****************************************************************************/
/* returns error */
int APP_CC
xrdp_sec_send_fastpath(struct xrdp_sec *self, struct stream *s)
{
int secFlags;
int fpOutputHeader;
int datalen;
int pdulen;
int pad;
LLOGLN(10, ("xrdp_sec_send_fastpath:"));
s_pop_layer(s, sec_hdr);
if (self->crypt_level == CRYPT_LEVEL_FIPS)
{
LLOGLN(10, ("xrdp_sec_send_fastpath: fips"));
pdulen = (int)(s->end - s->p);
datalen = pdulen - 15;
secFlags = 0x2;
fpOutputHeader = secFlags << 6;
out_uint8(s, fpOutputHeader);
pdulen |= 0x8000;
out_uint16_be(s, pdulen);
out_uint16_le(s, 16); /* crypto header size */
out_uint8(s, 1); /* fips version */
pad = (8 - (datalen % 8)) & 7;
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);
xrdp_sec_fips_encrypt(self, s->p + 8, datalen + pad);
}
else if (self->crypt_level > CRYPT_LEVEL_LOW)
{
LLOGLN(10, ("xrdp_sec_send_fastpath: crypt"));
pdulen = (int)(s->end - s->p);
datalen = pdulen - 11;
secFlags = 0x2;
fpOutputHeader = secFlags << 6;
out_uint8(s, fpOutputHeader);
pdulen |= 0x8000;
out_uint16_be(s, pdulen);
xrdp_sec_sign(self, s->p, 8, s->p + 8, datalen);
xrdp_sec_encrypt(self, s->p + 8, datalen);
}
else
{
LLOGLN(10, ("xrdp_sec_send_fastpath: no crypt"));
pdulen = (int)(s->end - s->p);
LLOGLN(10, ("xrdp_sec_send_fastpath: pdulen %d", pdulen));
secFlags = 0x0;
fpOutputHeader = secFlags << 6;
out_uint8(s, fpOutputHeader);
pdulen |= 0x8000;
out_uint16_be(s, pdulen);
}
if (xrdp_fastpath_send(self->fastpath_layer, s) != 0)
{
return 1;
}
return 0;
}
/*****************************************************************************/
/* http://msdn.microsoft.com/en-us/library/cc240510.aspx
2.2.1.3.2 Client Core Data (TS_UD_CS_CORE) */

Loading…
Cancel
Save