Windows Server 2019, Citrix VDA and the Broken, Not-so-Fast Reconnect

by Brandon Mitchell

If you’re using Windows Server 2019 with Citrix Virtual Apps, you may have a problem with users reconnecting to disconnected sessions that have idle timed out. I believe the adoption rate of Windows Server 2019 is low, and that’s why this issue remains relatively unknown.

There is a bug with Windows Server 2019 and Citrix Virtual Apps that remains unresolved even with the September 2019 Cumulative Updates and the 1909 Citrix VDA (latest as of this writing). This bug affects reconnecting to idle timed out ICA sessions only. ICA sessions that are forcibly disconnected by the user are not affected. RDP sessions are not affected.

With Windows Server 2019, there is a new feature called Remote Desktop Fast Reconnect. Fast Reconnect, introduced with Windows Server 2019, is a performance optimization to speed up reconnecting to a disconnected remote session.

Windows Server 2019 running December 2018 Cumulative Update and newer, the configuration for Fast Reconnect is supposed to work as follows.

  • For RDP connections, Fast Reconnect is on by default; but disabled when using smartcards.
  • For non-RDP (ICA) connections, Fast Reconnect is off by default, and it’s up to the protocol to decide the setting for the connection.

By default, the Citrix VDA enables Fast Reconnect on Windows Server 2019.

There is a two-minute grace period intended to allow users to respond to the idle disconnect dialog. If the user attempts to reconnect to their session within the grace, they will be able to successfully. If the user attempts to reconnect to their session outside grace, they will be unsuccessful. If the session has entered a disconnected state and the user is unable to reconnect, the only way to recover is to log off the disconnected session.

CDF traces debugged by Citrix reveal that the session ID set by Microsoft is not a valid session number:

26176,0,2019/08/30 10:39:04:38042,5076,3004,1,BrokerAgent,,0,,5,EntryExit,"=========>>>>> CONNECTION STARTING POINT PrepareSession entry Session Key 2779b29e-6a7c-44a0-8116-8c654aa6da0e, ConnectionMode Brokered, IsReconnect False, Launch Token 01bd0d65-fa96-44e3-b79b-f10e33ecaaa2, Brokering Token S-1-5-21-329068152-789336058-1177238915-128726",""

597826,0,2019/08/30 10:49:45:33584,3992,1096,0,Rpm, 1441,ctx::Connection::PreDisconnect,13,Information,"ctx::Connection::PreDisconnect: Session id 2, DisconnectReason = 0x3: ERRINFO_IDLE_TIMEOUT = 0x3",""
598797,0,2019/08/30 10:49:45:37930,340,1096,0,Rpm, ,1566,ctx::Connection::DisconnectNotify,13,Information,"ctx::Connection::DisconnectNotify: Session id 2 Calling RpmNotify NOTIFY_DISCONNECT",""
627166,0,2019/08/30 10:52:02:39960,7240,3004,1,BrokerAgent,,0,,5,EntryExit,"=========>>>>> CONNECTION STARTING POINT PrepareSession entry Session Key 2779b29e-6a7c-44a0-8116-8c654aa6da0e, ConnectionMode Brokered, IsReconnect True, Launch Token 7b876d0f-affa-4a56-89f8-879447780904, Brokering Token S-1-5-21-329068152-789336058-1177238915-128726",""
633140,0,2019/08/30 10:52:07:00725,6352,1096,0,Rpm, ,71,ctx::BaseSession::~BaseSession,13,EntryExit,"EXIT ---- ctx::Connection::GetSessionFastReconnect",""
633141,0,2019/08/30 10:52:07:00726,6352,1096,0,Rpm ,1315,ctx::Connection::AuthenticateClientToSession,9,Information,"ctx::Connection::AuthenticateClientToSession: Performing FSR to session 2",""

633145,0,2019/08/30 10:52:07:00726,6352,1096,0,Rpm, ,71,ctx::BaseSession::~BaseSession,13,EntryExit,"EXIT ---- ctx::Connection::AuthenticateClientToSession",""

633146,0,2019/08/30 10:52:07:00726,6352,1096,0,Rpm, 557,ctx::CWtsProtocolConnection::AuthenticateClientToSession,3,Information,"EXIT ---- ctx::CWtsProtocolConnection::AuthenticateClientToSession returning 0x0, Call Ticks 0",""

633147,0,2019/08/30 10:52:07:00792,6352,1096,0,Rpm, 1158,ctx::CWtsProtocolConnection::SetErrorInfo,12,EntryExit,"ENTRY --- ctx::CWtsProtocolConnection::SetErrorInfo: Session Id -1461024528",""

633148,0,2019/08/30 10:52:07:00811,6832,708,0,CtxAuth, ,5049,KrbLogonTerminated,9,Information,"Entry: KrbLogonTerminated",""

633149,0,2019/08/30 10:52:07:00811,6832,708,0,CtxAuth, ,5050,KrbLogonTerminated,9,Information,"Entry: KrbLogonTerminated (0000.4629250)",""

632322,0,2019/08/30 10:52:06:97069,6352,1096,0,Rpm ,1605,ctx::CWtsProtocolConnection::QueryProperty,14,Information,"ctx::CWtsProtocolConnection::QueryProperty: PROPERTY_TYPE_GET_FAST_RECONNECT, Citrix fast reconnect capability is currently enabled.",""

633147,0,2019/08/30 10:52:07:00792,6352,1096,0,Rpm ,1158,ctx::CWtsProtocolConnection::SetErrorInfo,12,EntryExit,"ENTRY --- ctx::CWtsProtocolConnection::SetErrorInfo: Session Id -1461024528",""
633155,0,2019/08/30 10:52:07:00821,6352,1096,0,Rpm, 1039,ctx::CWtsProtocolConnection::Close,12,EntryExit,"ENTRY --- ctx::CWtsProtocolConnection::Close: Session Id -1461024528",""

633182,0,2019/08/30 10:52:07:00834,6352,1096,0,Rpm, 1768,ctx::Connection::Close,12,EntryExit,"ENTRY --- ctx::Connection::Close: Session Id -1461024528",""

A trace during the same session captured by Microsoft reveals the failed reconnect attempt.

1554 [0]0448.0F50::08/30/19-09:52:06.9906538 [Termsrv] [New Connection] msg=Listener was notified of a new connection, Listener Name=ICA-CGP, ActivityID={00000000-0000-0000-0000-000000000000}

1575 [0]0448.0F50::08/30/19-09:52:07.0189175 [Termsrv] [GenericTrace] szOutput=ERR::getClientData call in invalid state Disconnected

1590 [0]0448.18D0::08/30/19-09:52:07.0306232 [Termsrv] [Auto Reconnect] msg=SessionAutoReconnectFlag returns, pVal=true, hr=The operation completed successfully. (0x00000000), SessionId=2

1591 [0]0448.18D0::08/30/19-09:52:07.0310364 [Termsrv] [GenericTrace] szOutput=INF::Retrieve cached last input time 132116495853549287, max 600000 for session 2

1592 [0]0448.18D0::08/30/19-09:52:07.0310403 [Termsrv] [Auto Reconnect] msg=Auto-reconnect exceed max idle, SessionId=2, maxIdleTime=600000, u64CurrentTime=132116503270224514, lastInputTimeBeforeDisconnect=132116495853549287, Delta=741667

Per Microsoft, the issue is the “AuthenticateClientToSession” callback to Citrix’s components are expected to fail when the session idle disconnect times out, and grace have elapsed. If that call fails with anything other than ERROR_TIMEOUT, Windows will fall back to a slower reconnect mechanism. But when it passes and Windows detects the timeout later, it is a hard failure. The expected failure code post idle disconnect and grace period is ERROR_NOT_AUTHENTICATED, but currently, any fault other than ERROR_TIMEOUT will force the slow to reconnect fallback.

The good news is there is a workaround to force the VDA to use the slower but functional reconnect method.

[HKEY_LOCAL_MACHINE\SOFTWARE\Citrix\Reconnect]

"FastReconnect"=dword:00000000

As of this writing, Microsoft has passed the ball to Citrix to review the handling of the AuthenticateClientToSession callback documented here:

https://docs.microsoft.com/en-us/windows/win32/api/wtsprotocol/nf-wtsprotocol-iwrdsprotocolconnection-authenticateclienttosession

Update:  Unfortunately it’s not referenced in CVAD 1912 LTSR fixed issues, but this is resolved and the FastReconnect registry entry is no longer necessary.

One comment

Leave a Reply