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;
|
RD_BOOL g_reconnect_loop = False;
|
||||||
uint8 g_client_random[SEC_RANDOM_SIZE];
|
uint8 g_client_random[SEC_RANDOM_SIZE];
|
||||||
RD_BOOL g_pending_resize = False;
|
RD_BOOL g_pending_resize = False;
|
||||||
|
RD_BOOL g_pending_resize_defer = True;
|
||||||
|
struct timeval g_pending_resize_defer_timer = {0};
|
||||||
|
|
||||||
#ifdef WITH_RDPSND
|
#ifdef WITH_RDPSND
|
||||||
RD_BOOL g_rdpsnd = False;
|
RD_BOOL g_rdpsnd = False;
|
||||||
@ -487,6 +489,8 @@ handle_disconnect_reason(RD_BOOL deactivated, uint16 reason)
|
|||||||
static void
|
static void
|
||||||
rdesktop_reset_state(void)
|
rdesktop_reset_state(void)
|
||||||
{
|
{
|
||||||
|
g_pending_resize_defer = True;
|
||||||
|
|
||||||
rdp_reset_state();
|
rdp_reset_state();
|
||||||
#ifdef WITH_SCARD
|
#ifdef WITH_SCARD
|
||||||
scard_reset_state();
|
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_bitmap_cache_persist_enable;
|
||||||
extern RD_BOOL g_numlock_sync;
|
extern RD_BOOL g_numlock_sync;
|
||||||
extern RD_BOOL g_pending_resize;
|
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 RD_BOOL g_network_error;
|
||||||
extern time_t g_wait_for_deactivate_ts;
|
extern time_t g_wait_for_deactivate_ts;
|
||||||
|
|
||||||
@ -1484,6 +1486,8 @@ process_ts_logon_info_extended(STREAM s)
|
|||||||
logger(Protocol, Debug,
|
logger(Protocol, Debug,
|
||||||
"process_ts_logon_info_extended(), saving Auto-Reconnect cookie, id=%u",
|
"process_ts_logon_info_extended(), saving Auto-Reconnect cookie, id=%u",
|
||||||
g_reconnect_logonid);
|
g_reconnect_logonid);
|
||||||
|
|
||||||
|
gettimeofday(&g_pending_resize_defer_timer, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
#define RDPEDISP_CHANNEL_NAME "Microsoft::Windows::RDS::DisplayControl"
|
#define RDPEDISP_CHANNEL_NAME "Microsoft::Windows::RDS::DisplayControl"
|
||||||
|
|
||||||
extern int g_dpi;
|
extern int g_dpi;
|
||||||
|
extern RD_BOOL g_pending_resize_defer;
|
||||||
|
|
||||||
static void rdpedisp_send(STREAM s);
|
static void rdpedisp_send(STREAM s);
|
||||||
static void rdpedisp_init_packet(STREAM s, uint32 type, uint32 length);
|
static void rdpedisp_init_packet(STREAM s, uint32 type, uint32 length);
|
||||||
@ -43,6 +44,9 @@ rdpedisp_process_caps_pdu(STREAM s)
|
|||||||
logger(Protocol, Debug,
|
logger(Protocol, Debug,
|
||||||
"rdpedisp_process_caps_pdu(), Max supported monitor area (square pixels) is %d",
|
"rdpedisp_process_caps_pdu(), Max supported monitor area (square pixels) is %d",
|
||||||
tmp[0] * tmp[1] * tmp[2]);
|
tmp[0] * tmp[1] * tmp[2]);
|
||||||
|
|
||||||
|
/* Start allowing session resizes */
|
||||||
|
g_pending_resize_defer = False;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
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_grab_keyboard;
|
||||||
extern RD_BOOL g_hide_decorations;
|
extern RD_BOOL g_hide_decorations;
|
||||||
extern RD_BOOL g_pending_resize;
|
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_title[];
|
||||||
extern char g_seamless_spawn_cmd[];
|
extern char g_seamless_spawn_cmd[];
|
||||||
/* Color depth of the RDP session.
|
/* Color depth of the RDP session.
|
||||||
@ -2993,6 +2996,21 @@ process_ui()
|
|||||||
return False;
|
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
|
static RD_BOOL
|
||||||
process_pending_resize ()
|
process_pending_resize ()
|
||||||
{
|
{
|
||||||
@ -3007,6 +3025,41 @@ process_pending_resize ()
|
|||||||
if (time_difference_in_ms(g_resize_timer, now) <= 500)
|
if (time_difference_in_ms(g_resize_timer, now) <= 500)
|
||||||
return False;
|
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 */
|
/* carry out a resize to desired size */
|
||||||
if (rdpedisp_is_available() == False)
|
if (rdpedisp_is_available() == False)
|
||||||
{
|
{
|
||||||
@ -3015,8 +3068,8 @@ process_pending_resize ()
|
|||||||
* server.
|
* server.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
g_requested_session_width = g_window_width;
|
g_requested_session_width = width;
|
||||||
g_requested_session_height = g_window_height;
|
g_requested_session_height = height;
|
||||||
|
|
||||||
logger(GUI, Verbose, "Window resize detected, reconnecting to new size %dx%d",
|
logger(GUI, Verbose, "Window resize detected, reconnecting to new size %dx%d",
|
||||||
g_requested_session_width,
|
g_requested_session_width,
|
||||||
|
Loading…
Reference in New Issue
Block a user