Defer pending resize until after autoreconnect cookie is received
Resize session using disconnect/reconnect sequence should not be performed before we have received an auto-reconnect cookie which is used for reconnecting to the session. There is a race when trying to reconnect at this point so a defer timer is used to delay this further from the point where the auto-reconnect cookie is received. Fixes a problem where a login prompt is shown upon reconnect even if the auto-reconnect cookie is available and used. Signed-off-by: Henrik Andersson <hean01@cendio.com> Signed-off-by: Karl Mikaelsson <derfian@cendio.se>
This commit is contained in:
parent
e112b69c61
commit
07abc9bade
@ -141,6 +141,8 @@ RD_BOOL g_has_reconnect_random = False;
|
||||
RD_BOOL g_reconnect_loop = False;
|
||||
uint8 g_client_random[SEC_RANDOM_SIZE];
|
||||
RD_BOOL g_pending_resize = False;
|
||||
RD_BOOL g_pending_resize_defer = True;
|
||||
struct timeval g_pending_resize_defer_timer = {0};
|
||||
|
||||
#ifdef WITH_RDPSND
|
||||
RD_BOOL g_rdpsnd = False;
|
||||
@ -487,6 +489,8 @@ handle_disconnect_reason(RD_BOOL deactivated, uint16 reason)
|
||||
static void
|
||||
rdesktop_reset_state(void)
|
||||
{
|
||||
g_pending_resize_defer = True;
|
||||
|
||||
rdp_reset_state();
|
||||
#ifdef WITH_SCARD
|
||||
scard_reset_state();
|
||||
|
4
rdp.c
4
rdp.c
@ -49,6 +49,8 @@ extern RD_BOOL g_bitmap_cache;
|
||||
extern RD_BOOL g_bitmap_cache_persist_enable;
|
||||
extern RD_BOOL g_numlock_sync;
|
||||
extern RD_BOOL g_pending_resize;
|
||||
extern RD_BOOL g_pending_resize_defer;
|
||||
extern struct timeval g_pending_resize_defer_timer;
|
||||
extern RD_BOOL g_network_error;
|
||||
extern time_t g_wait_for_deactivate_ts;
|
||||
|
||||
@ -1484,6 +1486,8 @@ process_ts_logon_info_extended(STREAM s)
|
||||
logger(Protocol, Debug,
|
||||
"process_ts_logon_info_extended(), saving Auto-Reconnect cookie, id=%u",
|
||||
g_reconnect_logonid);
|
||||
|
||||
gettimeofday(&g_pending_resize_defer_timer, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -27,6 +27,7 @@
|
||||
#define RDPEDISP_CHANNEL_NAME "Microsoft::Windows::RDS::DisplayControl"
|
||||
|
||||
extern int g_dpi;
|
||||
extern RD_BOOL g_pending_resize_defer;
|
||||
|
||||
static void rdpedisp_send(STREAM s);
|
||||
static void rdpedisp_init_packet(STREAM s, uint32 type, uint32 length);
|
||||
@ -43,6 +44,9 @@ rdpedisp_process_caps_pdu(STREAM s)
|
||||
logger(Protocol, Debug,
|
||||
"rdpedisp_process_caps_pdu(), Max supported monitor area (square pixels) is %d",
|
||||
tmp[0] * tmp[1] * tmp[2]);
|
||||
|
||||
/* Start allowing session resizes */
|
||||
g_pending_resize_defer = False;
|
||||
}
|
||||
|
||||
static void
|
||||
|
57
xwin.c
57
xwin.c
@ -58,6 +58,9 @@ extern RD_BOOL g_fullscreen;
|
||||
extern RD_BOOL g_grab_keyboard;
|
||||
extern RD_BOOL g_hide_decorations;
|
||||
extern RD_BOOL g_pending_resize;
|
||||
extern RD_BOOL g_pending_resize_defer;
|
||||
extern struct timeval g_pending_resize_defer_timer;
|
||||
|
||||
extern char g_title[];
|
||||
extern char g_seamless_spawn_cmd[];
|
||||
/* Color depth of the RDP session.
|
||||
@ -2993,6 +2996,21 @@ process_ui()
|
||||
return False;
|
||||
}
|
||||
|
||||
static RD_BOOL
|
||||
timeval_is_set(struct timeval *time)
|
||||
{
|
||||
return (time->tv_sec == 0 && time->tv_usec == 0) ? False : True;
|
||||
}
|
||||
|
||||
/* Handle a pending resize. Resize is handled by either a disconnect/reconnect
|
||||
sequence or online using RDPEDISP messages. Windows 2008 requires the use of
|
||||
disconnect/reconnect and to do that without user login credentials the
|
||||
auto-reconnect cookie is used. Windows 2008 seems sensitive to disconnects
|
||||
to early in the login sequence so we defer to resize until we get the cookie.
|
||||
|
||||
Windows 2016 on the other hand does not seem to send cookies but uses
|
||||
RDPEDISP so in this case we defer until the RDPEDISP channel is established.
|
||||
*/
|
||||
static RD_BOOL
|
||||
process_pending_resize ()
|
||||
{
|
||||
@ -3007,6 +3025,41 @@ process_pending_resize ()
|
||||
if (time_difference_in_ms(g_resize_timer, now) <= 500)
|
||||
return False;
|
||||
|
||||
/* There is a race problem when using disconnect / reconnect
|
||||
sequence were one sometimes would be presented with
|
||||
unexpected login window. Waiting a little bit extra after
|
||||
getting the reconnect cookie solves this problem. */
|
||||
if (timeval_is_set(&g_pending_resize_defer_timer) &&
|
||||
time_difference_in_ms(g_pending_resize_defer_timer, now) >= 100)
|
||||
{
|
||||
g_pending_resize_defer_timer.tv_sec = g_pending_resize_defer_timer.tv_usec = 0;
|
||||
g_pending_resize_defer = False;
|
||||
}
|
||||
|
||||
if (g_pending_resize_defer == True)
|
||||
return False;
|
||||
|
||||
/* only for fullscreen or x%-of-screen-sized windows */
|
||||
if (g_window_size_type == PercentageOfScreen
|
||||
|| g_window_size_type == Fullscreen
|
||||
|| g_fullscreen)
|
||||
{
|
||||
/* follow root window size */
|
||||
width = WidthOfScreen(g_screen);
|
||||
height = HeightOfScreen(g_screen);
|
||||
if (g_window_size_type == PercentageOfScreen)
|
||||
{
|
||||
/* TODO: Implement percentage of screen */
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Follow window size */
|
||||
width = g_window_width;
|
||||
height = g_window_height;
|
||||
}
|
||||
|
||||
|
||||
/* carry out a resize to desired size */
|
||||
if (rdpedisp_is_available() == False)
|
||||
{
|
||||
@ -3015,8 +3068,8 @@ process_pending_resize ()
|
||||
* server.
|
||||
*/
|
||||
|
||||
g_requested_session_width = g_window_width;
|
||||
g_requested_session_height = g_window_height;
|
||||
g_requested_session_width = width;
|
||||
g_requested_session_height = height;
|
||||
|
||||
logger(GUI, Verbose, "Window resize detected, reconnecting to new size %dx%d",
|
||||
g_requested_session_width,
|
||||
|
Loading…
Reference in New Issue
Block a user