Improve source_info commenting and fix neutrino slow link

This commit is contained in:
Matt Burt 2020-08-07 11:48:22 +01:00 committed by matt335672
parent 176b4b15a2
commit 1f8bb57fd6
11 changed files with 112 additions and 35 deletions

View File

@ -302,7 +302,7 @@ trans_check_wait_objs(struct trans *self)
int to_read = 0; int to_read = 0;
int read_so_far = 0; int read_so_far = 0;
int rv = 0; int rv = 0;
int cur_source; enum xrdp_source cur_source;
if (self == 0) if (self == 0)
{ {
@ -371,7 +371,7 @@ trans_check_wait_objs(struct trans *self)
} }
else if (self->trans_can_recv(self, self->sck, 0)) else if (self->trans_can_recv(self, self->sck, 0))
{ {
cur_source = 0; cur_source = XRDP_SOURCE_NONE;
if (self->si != 0) if (self->si != 0)
{ {
cur_source = self->si->cur_source; cur_source = self->si->cur_source;
@ -633,7 +633,7 @@ trans_write_copy_s(struct trans *self, struct stream *out_s)
init_stream(wait_s, size); init_stream(wait_s, size);
if (self->si != 0) if (self->si != 0)
{ {
if ((self->si->cur_source != 0) && if ((self->si->cur_source != XRDP_SOURCE_NONE) &&
(self->si->cur_source != self->my_source)) (self->si->cur_source != self->my_source))
{ {
self->si->source[self->si->cur_source] += size; self->si->source[self->si->cur_source] += size;

View File

@ -50,16 +50,43 @@ typedef int (*trans_can_recv_proc) (struct trans *self, int sck, int millis);
/* optional source info */ /* optional source info */
#define XRDP_SOURCE_NONE 0 enum xrdp_source
#define XRDP_SOURCE_CLIENT 1 {
#define XRDP_SOURCE_SESMAN 2 XRDP_SOURCE_NONE = 0,
#define XRDP_SOURCE_CHANSRV 3 XRDP_SOURCE_CLIENT,
#define XRDP_SOURCE_MOD 4 XRDP_SOURCE_SESMAN,
XRDP_SOURCE_CHANSRV,
XRDP_SOURCE_MOD,
XRDP_SOURCE_MAX_COUNT
};
/*
* @brief Provide flow control mechanism for (primarily) xrdp
*
* There is one of these data structures per-program.
*
* While input is being read from a 'struct trans' and processed, the
* cur_source member is set to the my_source member from the transport.
* During this processing, trans_write_copy() may be called to send output
* on another struct trans. If this happens, and the ouput needs to be
* buffered, trans_write_copy() can add the number of bytes generated by
* the input trans to the source field for the cur_source. This allows us to
* see how much output has been buffered for each input source.
*
* When the program assembles 'struct trans' objects to scan for input
* (normally in trans_get_wait_objs()), it is able to see how much buffered
* output is registered for each input. Inputs which have too much buffered
* output owing are skipped, and not considered for input.
*
* This provides a simple means of providing back-pressure on an input
* where the data it is providing is being processed and then sent out on
* a much slower link.
*/
struct source_info struct source_info
{ {
int cur_source; enum xrdp_source cur_source;
int source[7]; int source[XRDP_SOURCE_MAX_COUNT];
}; };
struct trans struct trans
@ -88,7 +115,7 @@ struct trans
trans_send_proc trans_send; trans_send_proc trans_send;
trans_can_recv_proc trans_can_recv; trans_can_recv_proc trans_can_recv;
struct source_info *si; struct source_info *si;
int my_source; enum xrdp_source my_source;
}; };
struct trans* struct trans*

View File

@ -26,6 +26,8 @@
#define CURRENT_MOD_VER 3 #define CURRENT_MOD_VER 3
struct source_info;
struct mod struct mod
{ {
int size; /* size of this struct */ int size; /* size of this struct */
@ -91,7 +93,7 @@ struct mod
tintptr handle; /* pointer to self as long */ tintptr handle; /* pointer to self as long */
tintptr wm; tintptr wm;
tintptr painter; tintptr painter;
tintptr si; struct source_info *si;
/* mod data */ /* mod data */
int sck; int sck;
int width; int width;

View File

@ -24,6 +24,7 @@
#include "xrdp-neutrinordp.h" #include "xrdp-neutrinordp.h"
#include "xrdp-color.h" #include "xrdp-color.h"
#include "xrdp_rail.h" #include "xrdp_rail.h"
#include "trans.h"
#include "log.h" #include "log.h"
#include <freerdp/settings.h> #include <freerdp/settings.h>
@ -39,6 +40,9 @@
#define LOG_LEVEL 1 #define LOG_LEVEL 1
#endif #endif
/* Max amount of buffered output data before we stop generating more */
#define MAX_QUEUED_MODULE_OUTPUT_DATA 50000
#define LLOG(_level, _args) \ #define LLOG(_level, _args) \
do { if (_level < LOG_LEVEL) { g_write _args ; } } while (0) do { if (_level < LOG_LEVEL) { g_write _args ; } } while (0)
#define LLOGLN(_level, _args) \ #define LLOGLN(_level, _args) \
@ -68,6 +72,13 @@ verifyColorMap(struct mod *mod)
LLOGLN(0, ("The colormap is all NULL")); LLOGLN(0, ("The colormap is all NULL"));
} }
/*****************************************************************************/
static int
get_queued_module_output_data(struct mod *mod)
{
return (mod->si != NULL) ? mod->si->source[XRDP_SOURCE_MOD] : 0;
}
/*****************************************************************************/ /*****************************************************************************/
/* return error */ /* return error */
static int static int
@ -516,6 +527,17 @@ lxrdp_get_wait_objs(struct mod *mod, tbus *read_objs, int *rcount,
boolean ok; boolean ok;
LLOGLN(12, ("lxrdp_get_wait_objs:")); LLOGLN(12, ("lxrdp_get_wait_objs:"));
/*
* Don't check this module for activity if our queued output data
* has already reached the limit
*/
if (get_queued_module_output_data(mod) > MAX_QUEUED_MODULE_OUTPUT_DATA)
{
*rcount = 0;
*wcount = 0;
}
else
{
rfds = (void **)read_objs; rfds = (void **)read_objs;
wfds = (void **)write_objs; wfds = (void **)write_objs;
ok = freerdp_get_fds(mod->inst, rfds, rcount, wfds, wcount); ok = freerdp_get_fds(mod->inst, rfds, rcount, wfds, wcount);
@ -525,6 +547,7 @@ lxrdp_get_wait_objs(struct mod *mod, tbus *read_objs, int *rcount,
LLOGLN(0, ("lxrdp_get_wait_objs: freerdp_get_fds failed")); LLOGLN(0, ("lxrdp_get_wait_objs: freerdp_get_fds failed"));
return 1; return 1;
} }
}
return 0; return 0;
} }
@ -536,13 +559,33 @@ lxrdp_check_wait_objs(struct mod *mod)
boolean ok; boolean ok;
LLOGLN(12, ("lxrdp_check_wait_objs:")); LLOGLN(12, ("lxrdp_check_wait_objs:"));
/*
* Only process the freerdp file descriptors if our queued output data
* has not reached the limit
*/
if (get_queued_module_output_data(mod) <= MAX_QUEUED_MODULE_OUTPUT_DATA)
{
/*
* Before checking the file descriptors, set the source info
* current source, so any data queued on output trans objects
* gets attributed to this module
*/
if (mod->si)
{
mod->si->cur_source = XRDP_SOURCE_MOD;
}
ok = freerdp_check_fds(mod->inst); ok = freerdp_check_fds(mod->inst);
if (mod->si)
{
mod->si->cur_source = XRDP_SOURCE_NONE;
}
if (!ok) if (!ok)
{ {
LLOGLN(0, ("lxrdp_check_wait_objs: freerdp_check_fds failed")); LLOGLN(0, ("lxrdp_check_wait_objs: freerdp_check_fds failed"));
return 1; return 1;
} }
}
return 0; return 0;
} }

View File

@ -61,6 +61,8 @@ struct pointer_item
#define CURRENT_MOD_VER 4 #define CURRENT_MOD_VER 4
struct source_info;
struct mod struct mod
{ {
int size; /* size of this struct */ int size; /* size of this struct */
@ -183,7 +185,7 @@ struct mod
tintptr handle; /* pointer to self as long */ tintptr handle; /* pointer to self as long */
tintptr wm; tintptr wm;
tintptr painter; tintptr painter;
tintptr si; struct source_info *si;
/* mod data */ /* mod data */
int sck; int sck;

View File

@ -1905,7 +1905,6 @@ lib_mod_connect(struct vnc *v)
int error; int error;
int i; int i;
int check_sec_result; int check_sec_result;
struct source_info *si;
v->server_msg(v, "VNC started connecting", 0); v->server_msg(v, "VNC started connecting", 0);
check_sec_result = 1; check_sec_result = 1;
@ -1955,8 +1954,7 @@ lib_mod_connect(struct vnc *v)
g_sprintf(text, "VNC connecting to %s %s", v->ip, con_port); g_sprintf(text, "VNC connecting to %s %s", v->ip, con_port);
v->server_msg(v, text, 0); v->server_msg(v, text, 0);
si = (struct source_info *) (v->si); v->trans->si = v->si;
v->trans->si = si;
v->trans->my_source = XRDP_SOURCE_MOD; v->trans->my_source = XRDP_SOURCE_MOD;
error = trans_connect(v->trans, v->ip, con_port, 3000); error = trans_connect(v->trans, v->ip, con_port, 3000);

View File

@ -56,6 +56,8 @@ enum vnc_resize_status
VRS_DONE VRS_DONE
}; };
struct source_info;
struct vnc struct vnc
{ {
int size; /* size of this struct */ int size; /* size of this struct */
@ -124,7 +126,7 @@ struct vnc
tintptr handle; /* pointer to self as long */ tintptr handle; /* pointer to self as long */
tintptr wm; tintptr wm;
tintptr painter; tintptr painter;
tintptr si; struct source_info *si;
/* mod data */ /* mod data */
int server_width; int server_width;
int server_height; int server_height;

View File

@ -471,7 +471,7 @@ xrdp_mm_setup_mod1(struct xrdp_mm *self)
self->mod->server_composite = server_composite; self->mod->server_composite = server_composite;
self->mod->server_paint_rects = server_paint_rects; self->mod->server_paint_rects = server_paint_rects;
self->mod->server_session_info = server_session_info; self->mod->server_session_info = server_session_info;
self->mod->si = (tintptr) &(self->wm->session->si); self->mod->si = &(self->wm->session->si);
} }
} }

View File

@ -30,6 +30,9 @@
#define MAX_NR_CHANNELS 16 #define MAX_NR_CHANNELS 16
#define MAX_CHANNEL_NAME 16 #define MAX_CHANNEL_NAME 16
struct source_info;
/* lib */ /* lib */
struct xrdp_mod struct xrdp_mod
{ {
@ -156,7 +159,7 @@ struct xrdp_mod
tintptr handle; /* pointer to self as int */ tintptr handle; /* pointer to self as int */
tintptr wm; /* struct xrdp_wm* */ tintptr wm; /* struct xrdp_wm* */
tintptr painter; tintptr painter;
tintptr si; struct source_info *si;
}; };
/* header for bmp file */ /* header for bmp file */

View File

@ -149,7 +149,6 @@ lib_mod_connect(struct mod *mod)
int use_uds; int use_uds;
struct stream *s; struct stream *s;
char con_port[256]; char con_port[256];
struct source_info *si;
LIB_DEBUG(mod, "in lib_mod_connect"); LIB_DEBUG(mod, "in lib_mod_connect");
@ -203,8 +202,7 @@ lib_mod_connect(struct mod *mod)
} }
} }
si = (struct source_info *) (mod->si); mod->trans->si = mod->si;
mod->trans->si = si;
mod->trans->my_source = XRDP_SOURCE_MOD; mod->trans->my_source = XRDP_SOURCE_MOD;
while (1) while (1)

View File

@ -29,6 +29,8 @@
#define CURRENT_MOD_VER 4 #define CURRENT_MOD_VER 4
struct source_info;
struct mod struct mod
{ {
int size; /* size of this struct */ int size; /* size of this struct */
@ -149,7 +151,7 @@ struct mod
tintptr handle; /* pointer to self as long */ tintptr handle; /* pointer to self as long */
tintptr wm; tintptr wm;
tintptr painter; tintptr painter;
tintptr si; struct source_info *si;
/* mod data */ /* mod data */
int width; int width;
int height; int height;