diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index f8207272d7..a117bce494 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -213,6 +213,6 @@ jobs: - run: sudo scripts/install_astyle_dependencies_with_apt.sh - run: scripts/install_astyle.sh $ASTYLE_REPO $ASTYLE_VER - name: Format code with astyle - run: scripts/run_astyle.sh + run: scripts/run_astyle.sh -v $ASTYLE_VER - name: Check code formatting run: git diff --exit-code diff --git a/common/Makefile.am b/common/Makefile.am index baed9f0d54..141addc8f6 100644 --- a/common/Makefile.am +++ b/common/Makefile.am @@ -71,6 +71,6 @@ libcommon_la_SOURCES = \ $(PIXMAN_SOURCES) libcommon_la_LIBADD = \ - -lpthread -lrt \ + -lpthread \ $(OPENSSL_LIBS) \ $(DLOPEN_LIBS) diff --git a/common/os_calls.c b/common/os_calls.c index 357df6da5a..5a788b5d76 100644 --- a/common/os_calls.c +++ b/common/os_calls.c @@ -434,23 +434,6 @@ g_tcp_socket(void) } } - option_len = sizeof(option_value); - - if (getsockopt(rv, SOL_SOCKET, SO_SNDBUF, (char *)&option_value, - &option_len) == 0) - { - if (option_value < (1024 * 32)) - { - option_value = 1024 * 32; - option_len = sizeof(option_value); - if (setsockopt(rv, SOL_SOCKET, SO_SNDBUF, (char *)&option_value, - option_len) < 0) - { - LOG(LOG_LEVEL_ERROR, "g_tcp_socket: setsockopt() failed"); - } - } - } - return rv; } diff --git a/docs/man/xrdp.ini.5.in b/docs/man/xrdp.ini.5.in index be6c82e365..e44327ce59 100644 --- a/docs/man/xrdp.ini.5.in +++ b/docs/man/xrdp.ini.5.in @@ -177,7 +177,9 @@ If set to \fB1\fP, \fBtrue\fP or \fByes\fP, no buffering will be performed in th \fBtcp_send_buffer_bytes\fP=\fIbuffer_size\fP .TP \fBtcp_recv_buffer_bytes\fP=\fIbuffer_size\fP -Specify send/recv buffer sizes in bytes. The default value depends on operating system. +Specify send/recv buffer sizes in bytes. The default value depends on +the operating system. It is recommended not to set these on systems with +dynamic TCP buffer sizing .TP \fBtls_ciphers\fP=\fIcipher_suite\fP diff --git a/instfiles/xrdp.service.in b/instfiles/xrdp.service.in index be24535a27..92ce035a69 100644 --- a/instfiles/xrdp.service.in +++ b/instfiles/xrdp.service.in @@ -10,9 +10,7 @@ EnvironmentFile=-@sysconfdir@/sysconfig/xrdp EnvironmentFile=-@sysconfdir@/default/xrdp ExecStart=@sbindir@/xrdp $XRDP_OPTIONS --nodaemon SystemCallArchitectures=native -SystemCallFilter=@basic-io @file-system @io-event @ipc @network-io @process -SystemCallFilter=@signal @system-service ioctl madvise sysinfo uname -SystemCallErrorNumber=EPERM +SystemCallFilter=@system-service [Install] WantedBy=multi-user.target diff --git a/librfxcodec b/librfxcodec index ab9b65cee1..015fdffff9 160000 --- a/librfxcodec +++ b/librfxcodec @@ -1 +1 @@ -Subproject commit ab9b65cee1d96eefe154de721fb375f7a4d3946a +Subproject commit 015fdffff98584c47966aca617acdc0d1e6dbdca diff --git a/scripts/run_astyle.sh b/scripts/run_astyle.sh index 43b47e4cbc..f3384da086 100755 --- a/scripts/run_astyle.sh +++ b/scripts/run_astyle.sh @@ -2,12 +2,15 @@ # Script to run astyle on the code # -# Usage: /path/to/run_astyle.sh +# Usage: /path/to/run_astyle.sh [ -v ASTYLE_VER] # +# - If -v ASTYLE_VER is specified, that version of astyle is run from +# ~/astyle.local (whether or not it's there!). Use install_astyle.sh +# to install a new version. + # Note: the script must be run from the root directory of the xrdp repository INSTALL_ROOT=~/astyle.local -ASTYLE_FROM_XRDP=$INSTALL_ROOT/3.4.12/usr/bin/astyle MIN_ASTYLE_VER="3.1" # ---------------------------------------------------------------------------- @@ -15,53 +18,66 @@ MIN_ASTYLE_VER="3.1" # ---------------------------------------------------------------------------- usage() { - echo "** Usage: $0" - echo " e.g. $0" + echo "** Usage: $0 [ -v version]" + echo " e.g. $0 -v 3.4.12" } >&2 # ---------------------------------------------------------------------------- # M A I N # ---------------------------------------------------------------------------- +# Figure out ASTYLE setting, if any. Currently '-v' must be the first +# argument on the command line. +case "$1" in + -v) # Version is separate parameter + if [ $# -ge 2 ]; then + ASTYLE="$INSTALL_ROOT/$2/usr/bin/astyle" + shift 2 + else + echo "** ignoring '-v' with no arg" >&2 + shift 1 + fi + ;; + -v*) # Version is in same parameter + # ${parameter#word} is not supported by classic Bourne shell, + # but it is on bash, dash, etc. If it doesn't work on your shell, + # don't use this form! + ASTYLE="$INSTALL_ROOT/${1#-v}/usr/bin/astyle" + shift 1 +esac + +if [ -z "$ASTYLE" ]; then + ASTYLE=astyle +fi + if [ $# -ne 0 ]; then usage exit 1 fi -# check if the built-in astyle meets the minimum requrements -ASTYLE_FROM_OS_VER_OUTPUT=`astyle --version | grep "Artistic Style Version" | cut -d' ' -f4` -ASTYLE="" -ERROR_MESSAGE="" -if [ ! -z "$ASTYLE_FROM_OS_VER_OUTPUT" ]; then - # astyle is installed, so check if it's version meets the minimum requirements - LOWEST_VERSION=`echo -e "$MIN_ASTYLE_VER\n$ASTYLE_FROM_OS_VER_OUTPUT" | sort -V | head -n1` - if [ "$MIN_ASTYLE_VER" = "$LOWEST_VERSION" ]; then - ASTYLE=astyle - else +# check if the selected astyle meets the minimum requrements +ASTYLE_VER_OUTPUT=`$ASTYLE --version 2>/dev/null | grep "Artistic Style Version" | cut -d' ' -f4` + +if [ ! -z "$ASTYLE_VER_OUTPUT" ]; then + # Check the version meets the minimum requirements + LOWEST_VERSION=`{ echo "$MIN_ASTYLE_VER" ; echo "$ASTYLE_VER_OUTPUT"; } | sort -V | head -n1` + if [ "$MIN_ASTYLE_VER" != "$LOWEST_VERSION" ]; then ERROR_MESSAGE="The version of astyle installed does not meet the minimum version requirement: >= $MIN_ASTYLE_VER " fi -else +elif [ "$ASTYLE" = astyle ]; then ERROR_MESSAGE="astyle is not installed on the system path" -fi - -if [ -z "$ASTYLE" ]; then - # astyle from the os is invlid, fallback to the xrdp version if it is installed - if [ -x "$ASTYLE_FROM_XRDP" ]; then - ASTYLE="$ASTYLE_FROM_XRDP" - ERROR_MESSAGE="" - else - ERROR_MESSAGE="${ERROR_MESSAGE}\nastyle $MIN_ASTYLE_VER is not installed at the expected path: $ASTYLE_FROM_XRDP" - fi +else + ERROR_MESSAGE="Can't find $ASTYLE" fi if [ ! -z "$ERROR_MESSAGE" ]; then - echo "$ERROR_MESSAGE" + echo "$ERROR_MESSAGE" >&2 exit 1 fi if [ ! -f "astyle_config.as" ]; then - echo "$0 must be run from the root xrdp repository directory which " - echo "contains the 'astyle_config.as' file." + echo "$0 must be run from the root xrdp repository directory which " >&2 + echo "contains the 'astyle_config.as' file." >&2 exit 2 fi @@ -72,3 +88,5 @@ ASTYLE_FLAGS="--options=astyle_config.as --exclude=third_party ./\*.c ./\*.h" echo "Command: $ASTYLE $ASTYLE_FLAGS" "$ASTYLE" $ASTYLE_FLAGS } + +exit $? diff --git a/sesman/scp_process.c b/sesman/scp_process.c index 3f0c363078..f05e7db418 100644 --- a/sesman/scp_process.c +++ b/sesman/scp_process.c @@ -323,6 +323,9 @@ process_logout_request(struct pre_session_item *psi) static int create_xrdp_socket_path(uid_t uid) { + // Owner all permissions, group read+execute +#define RWX_PERMS 0x750 + int rv = 1; const char *sockdir_group = g_cfg->sec.session_sockdir_group; int gid = 0; // Default if no group specified @@ -330,14 +333,21 @@ create_xrdp_socket_path(uid_t uid) char sockdir[XRDP_SOCKETS_MAXPATH]; g_snprintf(sockdir, sizeof(sockdir), XRDP_SOCKET_PATH, (int)uid); - // Create directory permissions 0x750, if it doesn't exist already. - int old_umask = g_umask_hex(0x750 ^ 0x777); + // Create directory permissions RWX_PERMS, if it doesn't exist already + // (our os_calls layer doesn't allow us to set the SGID bit here) + int old_umask = g_umask_hex(RWX_PERMS ^ 0x777); if (!g_directory_exist(sockdir) && !g_create_dir(sockdir)) { LOG(LOG_LEVEL_ERROR, "create_xrdp_socket_path: Can't create %s [%s]", sockdir, g_get_strerror()); } + else if (g_chmod_hex(sockdir, RWX_PERMS | 0x2000) != 0) + { + LOG(LOG_LEVEL_ERROR, + "create_xrdp_socket_path: Can't set SGID bit on %s [%s]", + sockdir, g_get_strerror()); + } else if (sockdir_group != NULL && sockdir_group[0] != '\0' && g_getgroup_info(sockdir_group, &gid) != 0) { @@ -358,6 +368,7 @@ create_xrdp_socket_path(uid_t uid) (void)g_umask_hex(old_umask); return rv; +#undef RWX_PERMS } /******************************************************************************/ diff --git a/xrdp/xrdp.ini.in b/xrdp/xrdp.ini.in index 8a50a414d4..11ecada6f8 100644 --- a/xrdp/xrdp.ini.in +++ b/xrdp/xrdp.ini.in @@ -35,7 +35,10 @@ tcp_nodelay=true ; if the network connection disappear without close messages the connection will be closed tcp_keepalive=true -; set tcp send/recv buffer (for experts) +; set tcp send/recv buffer +; These parameters are largely historic. On systems with dynamic TCP +; buffer sizes, setting them manually will either impact performance or +; waste memory #tcp_send_buffer_bytes=32768 #tcp_recv_buffer_bytes=32768 diff --git a/xrdp/xrdp_encoder.c b/xrdp/xrdp_encoder.c index 5717c8fa06..b7a51e5e44 100644 --- a/xrdp/xrdp_encoder.c +++ b/xrdp/xrdp_encoder.c @@ -28,11 +28,22 @@ #include "thread_calls.h" #include "fifo.h" #include "xrdp_egfx.h" +#include "string_calls.h" #ifdef XRDP_RFXCODEC #include "rfxcodec_encode.h" #endif +#define DEFAULT_XRDP_GFX_FRAMES_IN_FLIGHT 2 +/* limits used for validate env var XRDP_GFX_FRAMES_IN_FLIGHT */ +#define MIN_XRDP_GFX_FRAMES_IN_FLIGHT 1 +#define MAX_XRDP_GFX_FRAMES_IN_FLIGHT 16 + +#define DEFAULT_XRDP_GFX_MAX_COMPRESSED_BYTES (3 * 1024 * 1024) +/* limits used for validate env var XRDP_GFX_MAX_COMPRESSED_BYTES */ +#define MIN_XRDP_GFX_MAX_COMPRESSED_BYTES (64 * 1024) +#define MAX_XRDP_GFX_MAX_COMPRESSED_BYTES (256 * 1024 * 1024) + #define XRDP_SURCMD_PREFIX_BYTES 256 #define OUT_DATA_BYTES_DEFAULT_SIZE (16 * 1024 * 1024) @@ -85,40 +96,6 @@ xrdp_enc_data_done_destructor(void *item, void *closure) g_free(enc_done); } -/*****************************************************************************/ -static unsigned int -get_largest_monitor_pixels(struct xrdp_mm *mm) -{ - unsigned int max_pixels; - - struct xrdp_client_info *client_info = mm->wm->client_info; - struct display_size_description *display_sizes; - display_sizes = &client_info->display_sizes; - - if (display_sizes->monitorCount < 1) - { - max_pixels = display_sizes->session_width * - display_sizes->session_height; - } - else - { - max_pixels = 0; - struct monitor_info *minfo = display_sizes->minfo; - unsigned int i; - for (i = 0 ; i < display_sizes->monitorCount; ++i) - { - unsigned int pixels = (minfo[i].right + 1) - minfo[i].left; - pixels *= (minfo[i].bottom + 1) - minfo[i].top; - if (pixels > max_pixels) - { - max_pixels = pixels; - } - } - } - - return max_pixels; -} - /*****************************************************************************/ struct xrdp_encoder * xrdp_encoder_create(struct xrdp_mm *mm) @@ -223,10 +200,44 @@ xrdp_encoder_create(struct xrdp_mm *mm) self->xrdp_encoder_term = g_create_wait_obj(buf); if (client_info->gfx) { - // Assume compressor needs to cope with largest monitor with - // ineffective compression - self->frames_in_flight = 2; - self->max_compressed_bytes = get_largest_monitor_pixels(mm) * 4; + const char *env_var = g_getenv("XRDP_GFX_FRAMES_IN_FLIGHT"); + self->frames_in_flight = DEFAULT_XRDP_GFX_FRAMES_IN_FLIGHT; + if (env_var != NULL) + { + int fif = g_atoix(env_var); + if (fif >= MIN_XRDP_GFX_FRAMES_IN_FLIGHT && + fif <= MAX_XRDP_GFX_FRAMES_IN_FLIGHT) + { + self->frames_in_flight = fif; + LOG(LOG_LEVEL_INFO, "xrdp_encoder_create: " + "XRDP_GFX_FRAMES_IN_FLIGHT set to %d", fif); + } + else + { + LOG(LOG_LEVEL_INFO, "xrdp_encoder_create: " + "XRDP_GFX_FRAMES_IN_FLIGHT set but invalid %s", + env_var); + } + } + env_var = g_getenv("XRDP_GFX_MAX_COMPRESSED_BYTES"); + self->max_compressed_bytes = DEFAULT_XRDP_GFX_MAX_COMPRESSED_BYTES; + if (env_var != NULL) + { + int mcb = g_atoix(env_var); + if (mcb >= MIN_XRDP_GFX_MAX_COMPRESSED_BYTES && + mcb <= MAX_XRDP_GFX_MAX_COMPRESSED_BYTES) + { + self->max_compressed_bytes = mcb; + LOG(LOG_LEVEL_INFO, "xrdp_encoder_create: " + "XRDP_GFX_MAX_COMPRESSED_BYTES set to %d", mcb); + } + else + { + LOG(LOG_LEVEL_INFO, "xrdp_encoder_create: " + "XRDP_GFX_MAX_COMPRESSED_BYTES set but invalid %s", + env_var); + } + } LOG_DEVEL(LOG_LEVEL_INFO, "Using %d max_compressed_bytes for encoder", self->max_compressed_bytes); } @@ -563,16 +574,50 @@ process_enc_h264(struct xrdp_encoder *self, XRDP_ENC_DATA *enc) #ifdef XRDP_RFXCODEC +/*****************************************************************************/ +static int +gfx_send_done(struct xrdp_encoder *self, XRDP_ENC_DATA *enc, + int comp_bytes, int pad_bytes, char *comp_pad_data, + int got_frame_id, int frame_id, int is_last) + +{ + XRDP_ENC_DATA_DONE *enc_done; + + enc_done = g_new0(XRDP_ENC_DATA_DONE, 1); + if (enc_done == NULL) + { + return 1; + } + ENC_SET_BIT(enc_done->flags, ENC_DONE_FLAGS_GFX_BIT); + enc_done->enc = enc; + enc_done->last = is_last; + enc_done->pad_bytes = pad_bytes; + enc_done->comp_bytes = comp_bytes; + enc_done->comp_pad_data = comp_pad_data; + if (got_frame_id) + { + ENC_SET_BIT(enc_done->flags, ENC_DONE_FLAGS_FRAME_ID_BIT); + enc_done->frame_id = frame_id; + } + /* inform main thread done */ + tc_mutex_lock(self->mutex); + fifo_add_item(self->fifo_processed, enc_done); + tc_mutex_unlock(self->mutex); + /* signal completion for main thread */ + g_set_wait_obj(self->xrdp_encoder_event_processed); + return 0; +} + /*****************************************************************************/ static struct stream * gfx_wiretosurface1(struct xrdp_encoder *self, struct xrdp_egfx_bulk *bulk, struct stream *in_s, - struct xrdp_enc_gfx_cmd *enc_gfx_cmd) + XRDP_ENC_DATA *enc) { (void)self; (void)bulk; (void)in_s; - (void)enc_gfx_cmd; + (void)enc; return NULL; } @@ -580,7 +625,7 @@ gfx_wiretosurface1(struct xrdp_encoder *self, static struct stream * gfx_wiretosurface2(struct xrdp_encoder *self, struct xrdp_egfx_bulk *bulk, struct stream *in_s, - struct xrdp_enc_gfx_cmd *enc_gfx_cmd) + XRDP_ENC_DATA *enc) { int index; int surface_id; @@ -598,10 +643,10 @@ gfx_wiretosurface2(struct xrdp_encoder *self, int bitmap_data_length; struct rfx_tile *tiles; struct rfx_rect *rfxrects; + int tiles_compressed; int flags; + int total_tiles; int tiles_written; - int do_free; - int do_send; int mon_index; if (!s_check_rem(in_s, 15)) @@ -687,58 +732,71 @@ gfx_wiretosurface2(struct xrdp_encoder *self, RFX_FLAGS_RLGR1 | RFX_FLAGS_PRO1); if (self->codec_handle_prfx_gfx[mon_index] == NULL) { + g_free(tiles); + g_free(rfxrects); return NULL; } } - - do_free = 0; - do_send = 0; - if (ENC_IS_BIT_SET(flags, 0)) + bitmap_data_length = self->max_compressed_bytes; + bitmap_data = g_new(char, bitmap_data_length); + if (bitmap_data == NULL) { - /* already compressed */ - bitmap_data_length = enc_gfx_cmd->data_bytes; - bitmap_data = enc_gfx_cmd->data; - do_send = 1; + g_free(tiles); + g_free(rfxrects); + return NULL; } - else + rv = NULL; + tiles_written = 0; + total_tiles = num_rects_c; + for (;;) { - bitmap_data_length = self->max_compressed_bytes; - bitmap_data = g_new(char, bitmap_data_length); - if (bitmap_data == NULL) + tiles_compressed = + rfxcodec_encode(self->codec_handle_prfx_gfx[mon_index], + bitmap_data, + &bitmap_data_length, + enc->u.gfx.data, + width, height, + ((width + 63) & ~63) * 4, + rfxrects, num_rects_d, + tiles + tiles_written, total_tiles - tiles_written, + self->quants, self->num_quants); + if (tiles_compressed < 1) { - g_free(tiles); - g_free(rfxrects); - return NULL; - } - do_free = 1; - tiles_written = rfxcodec_encode(self->codec_handle_prfx_gfx[mon_index], - bitmap_data, - &bitmap_data_length, - enc_gfx_cmd->data, - width, height, - ((width + 63) & ~63) * 4, - rfxrects, num_rects_d, - tiles, num_rects_c, - self->quants, self->num_quants); - if (tiles_written > 0) - { - do_send = 1; + break; } - } - g_free(tiles); - g_free(rfxrects); - rv = NULL; - if (do_send) - { + tiles_written += tiles_compressed; rv = xrdp_egfx_wire_to_surface2(bulk, surface_id, codec_id, codec_context_id, pixel_format, bitmap_data, bitmap_data_length); + if (rv == NULL) + { + break; + } + LOG_DEVEL(LOG_LEVEL_ERROR, "gfx_wiretosurface2: " + "tiles_compressed %d total_tiles %d tiles_written %d", + tiles_compressed, total_tiles, + tiles_written); + if (tiles_written >= total_tiles) + { + /* ok, done with last tile set */ + break; + } + /* we have another tile set, send this one to main thread */ + if (gfx_send_done(self, enc, (int)(rv->end - rv->data), 0, + rv->data, 0, 0, 0) != 0) + { + free_stream(rv); + rv = NULL; + break; + } + g_free(rv); /* don't call free_stream() here so s->data is valid */ + rv = NULL; + bitmap_data_length = self->max_compressed_bytes; } - if (do_free) - { - g_free(bitmap_data); - } + g_free(tiles); + g_free(rfxrects); + g_free(bitmap_data); return rv; } @@ -939,20 +997,14 @@ process_enc_egfx(struct xrdp_encoder *self, XRDP_ENC_DATA *enc) struct stream *s; struct stream in_s; struct xrdp_egfx_bulk *bulk; - XRDP_ENC_DATA_DONE *enc_done; - struct fifo *fifo_processed; - tbus mutex; - tbus event_processed; int cmd_id; int cmd_bytes; int frame_id; int got_frame_id; + int error; char *holdp; char *holdend; - fifo_processed = self->fifo_processed; - mutex = self->mutex; - event_processed = self->xrdp_encoder_event_processed; bulk = self->mm->egfx->bulk; g_memset(&in_s, 0, sizeof(in_s)); in_s.data = enc->u.gfx.cmd; @@ -977,10 +1029,10 @@ process_enc_egfx(struct xrdp_encoder *self, XRDP_ENC_DATA *enc) switch (cmd_id) { case XR_RDPGFX_CMDID_WIRETOSURFACE_1: /* 0x0001 */ - s = gfx_wiretosurface1(self, bulk, &in_s, &(enc->u.gfx)); + s = gfx_wiretosurface1(self, bulk, &in_s, enc); break; case XR_RDPGFX_CMDID_WIRETOSURFACE_2: /* 0x0002 */ - s = gfx_wiretosurface2(self, bulk, &in_s, &(enc->u.gfx)); + s = gfx_wiretosurface2(self, bulk, &in_s, enc); break; case XR_RDPGFX_CMDID_SOLIDFILL: /* 0x0004 */ s = gfx_solidfill(self, bulk, &in_s); @@ -1010,38 +1062,24 @@ process_enc_egfx(struct xrdp_encoder *self, XRDP_ENC_DATA *enc) default: break; } - if (s == NULL) - { - LOG(LOG_LEVEL_ERROR, "process_enc_egfx: cmd_id %d s = nil", cmd_id); - return 1; - } /* setup for next cmd */ in_s.p = holdp + cmd_bytes; in_s.end = holdend; - /* setup enc_done struct */ - enc_done = g_new0(XRDP_ENC_DATA_DONE, 1); - if (enc_done == NULL) + if (s != NULL) { - free_stream(s); - return 1; - } - ENC_SET_BIT(enc_done->flags, ENC_DONE_FLAGS_GFX_BIT); - enc_done->enc = enc; - enc_done->last = !s_check_rem(&in_s, 8); - enc_done->comp_bytes = (int) (s->end - s->data); - enc_done->comp_pad_data = s->data; - if (got_frame_id) - { - ENC_SET_BIT(enc_done->flags, ENC_DONE_FLAGS_FRAME_ID_BIT); - enc_done->frame_id = frame_id; + /* send message to main thread */ + error = gfx_send_done(self, enc, (int) (s->end - s->data), + 0, s->data, got_frame_id, frame_id, + !s_check_rem(&in_s, 8)); + if (error != 0) + { + LOG(LOG_LEVEL_ERROR, "process_enc_egfx: gfx_send_done failed " + "error %d", error); + free_stream(s); + return 1; + } + g_free(s); /* don't call free_stream() here so s->data is valid */ } - g_free(s); /* don't call free_stream() here so s->data is valid */ - /* inform main thread done */ - tc_mutex_lock(mutex); - fifo_add_item(fifo_processed, enc_done); - tc_mutex_unlock(mutex); - /* signal completion for main thread */ - g_set_wait_obj(event_processed); } return 0; } diff --git a/xrdp/xrdp_listen.c b/xrdp/xrdp_listen.c index 5dd9c19b56..099b7735ac 100644 --- a/xrdp/xrdp_listen.c +++ b/xrdp/xrdp_listen.c @@ -716,47 +716,45 @@ xrdp_listen_process_startup_params(struct xrdp_listen *self) if (startup_params->tcp_send_buffer_bytes > 0) { bytes = startup_params->tcp_send_buffer_bytes; - LOG(LOG_LEVEL_INFO, "setting send buffer to %d bytes", - bytes); if (g_sck_set_send_buffer_bytes(ltrans->sck, bytes) != 0) { LOG(LOG_LEVEL_WARNING, "error setting send buffer"); } + else if (g_sck_get_send_buffer_bytes(ltrans->sck, &bytes) != 0) + { + LOG(LOG_LEVEL_WARNING, "error getting send buffer"); + } + else if (bytes != startup_params->tcp_send_buffer_bytes) + { + LOG(LOG_LEVEL_WARNING, "send buffer set to %d " + "bytes but %d bytes requested", bytes, + startup_params->tcp_send_buffer_bytes); + } else { - if (g_sck_get_send_buffer_bytes(ltrans->sck, &bytes) != 0) - { - LOG(LOG_LEVEL_WARNING, "error getting send " - "buffer"); - } - else - { - LOG(LOG_LEVEL_INFO, "send buffer set to %d " - "bytes", bytes); - } + LOG(LOG_LEVEL_INFO, "send buffer set to %d bytes", bytes); } } if (startup_params->tcp_recv_buffer_bytes > 0) { bytes = startup_params->tcp_recv_buffer_bytes; - LOG(LOG_LEVEL_INFO, "setting recv buffer to %d bytes", - bytes); if (g_sck_set_recv_buffer_bytes(ltrans->sck, bytes) != 0) { LOG(LOG_LEVEL_WARNING, "error setting recv buffer"); } + else if (g_sck_get_recv_buffer_bytes(ltrans->sck, &bytes) != 0) + { + LOG(LOG_LEVEL_WARNING, "error getting recv buffer"); + } + else if (bytes != startup_params->tcp_recv_buffer_bytes) + { + LOG(LOG_LEVEL_WARNING, "recv buffer set to %d " + "bytes but %d bytes requested", bytes, + startup_params->tcp_recv_buffer_bytes); + } else { - if (g_sck_get_recv_buffer_bytes(ltrans->sck, &bytes) != 0) - { - LOG(LOG_LEVEL_WARNING, "error getting recv " - "buffer"); - } - else - { - LOG(LOG_LEVEL_INFO, "recv buffer set to %d " - "bytes", bytes); - } + LOG(LOG_LEVEL_INFO, "recv buffer set to %d bytes", bytes); } } } diff --git a/xrdp/xrdp_mm.c b/xrdp/xrdp_mm.c index e15cfd0bda..61e097e663 100644 --- a/xrdp/xrdp_mm.c +++ b/xrdp/xrdp_mm.c @@ -3477,7 +3477,7 @@ xrdp_mm_process_enc_done(struct xrdp_mm *self) y = enc_done->y; cx = enc_done->cx; cy = enc_done->cy; - if (!enc_done->continuation) + if (client_ack && !enc_done->continuation) { libxrdp_fastpath_send_frame_marker(self->wm->session, 0, enc_done->frame_id); @@ -3489,7 +3489,7 @@ xrdp_mm_process_enc_done(struct xrdp_mm *self) x, y, x + cx, y + cy, 32, self->encoder->codec_id, cx, cy); - if (enc_done->last) + if (client_ack && enc_done->last) { libxrdp_fastpath_send_frame_marker(self->wm->session, 1, enc_done->frame_id);