xfreerdp: partial reconnect fixes

This commit is contained in:
Marc-André Moreau 2015-02-05 17:01:56 -05:00
parent fdde017526
commit 82d58086db
8 changed files with 118 additions and 48 deletions

View File

@ -283,6 +283,8 @@ void dvcman_free(IWTSVirtualChannelManager* pChannelMgr)
free(listener);
}
dvcman->num_listeners = 0;
for (i = 0; i < dvcman->num_plugins; i++)
{
pPlugin = dvcman->plugins[i];
@ -291,7 +293,10 @@ void dvcman_free(IWTSVirtualChannelManager* pChannelMgr)
pPlugin->Terminated(pPlugin);
}
dvcman->num_plugins = 0;
StreamPool_Free(dvcman->pool);
free(dvcman);
}

View File

@ -955,9 +955,16 @@ static int rdpgfx_plugin_terminated(IWTSPlugin* pPlugin)
WLog_Print(gfx->log, WLOG_DEBUG, "Terminated");
if (gfx->listener_callback)
{
free(gfx->listener_callback);
gfx->listener_callback = NULL;
}
zgfx_context_free(gfx->zgfx);
if (gfx->zgfx)
{
zgfx_context_free(gfx->zgfx);
gfx->zgfx = NULL;
}
count = HashTable_GetKeys(gfx->SurfaceTable, &pKeys);

View File

@ -71,7 +71,6 @@ int main(int argc, char* argv[])
thread = freerdp_client_get_thread(context);
WaitForSingleObject(thread, INFINITE);
GetExitCodeThread(thread, &dwExitCode);
freerdp_client_stop(context);

View File

@ -203,7 +203,7 @@ void xf_draw_screen(xfContext* xfc, int x, int y, int w, int h)
{
if (w == 0 || h == 0)
{
WLog_WARN(TAG, "invalid width and/or height specified: w=%d h=%d", w, h);
WLog_WARN(TAG, "invalid width and/or height specified: w=%d h=%d", w, h);
return;
}
@ -788,7 +788,6 @@ int _xf_error_handler(Display* d, XErrorEvent* ev)
static void xf_post_disconnect(freerdp* instance)
{
xfContext* xfc;
rdpChannels* channels = channels = instance->context->channels;
if (!instance || !instance->context || !instance->settings)
return;
@ -895,7 +894,7 @@ BOOL xf_pre_connect(freerdp* instance)
{
if (!XInitThreads())
{
WLog_WARN(TAG, "XInitThreads() failure");
WLog_WARN(TAG, "XInitThreads() failure");
xfc->UseXThreads = FALSE;
}
}
@ -911,7 +910,7 @@ BOOL xf_pre_connect(freerdp* instance)
if (xfc->debug)
{
WLog_INFO(TAG, "Enabling X11 debug mode.");
WLog_INFO(TAG, "Enabling X11 debug mode.");
XSynchronize(xfc->display, TRUE);
_def_error_handler = XSetErrorHandler(_xf_error_handler);
}
@ -1127,6 +1126,7 @@ BOOL xf_post_connect(freerdp *instance)
palette_cache_register_callbacks(instance->update);
instance->update->BitmapUpdate = xf_gdi_bitmap_update;
}
instance->update->PlaySound = xf_play_sound;
instance->update->SetKeyboardIndicators = xf_keyboard_set_indicators;
@ -1360,39 +1360,44 @@ void* xf_input_thread(void *arg)
BOOL xf_auto_reconnect(freerdp* instance)
{
UINT32 maxRetries;
UINT32 numRetries = 0;
xfContext* xfc = (xfContext*) instance->context;
UINT32 num_retries = 0;
UINT32 max_retries = instance->settings->AutoReconnectMaxRetries;
rdpSettings* settings = xfc->settings;
maxRetries = settings->AutoReconnectMaxRetries;
/* Only auto reconnect on network disconnects. */
if (freerdp_error_info(instance) != 0)
return FALSE;
/* A network disconnect was detected */
WLog_INFO(TAG, "Network disconnect!");
WLog_INFO(TAG, "Network disconnect!");
if (!instance->settings->AutoReconnectionEnabled)
if (!settings->AutoReconnectionEnabled)
{
/* No auto-reconnect - just quit */
return FALSE;
}
/* Perform an auto-reconnect. */
for (;;)
while (TRUE)
{
/* Quit retrying if max retries has been exceeded */
if (num_retries++ >= max_retries)
if (numRetries++ >= maxRetries)
{
return FALSE;
}
/* Attempt the next reconnect */
WLog_INFO(TAG, "Attempting reconnect (%u of %u)", num_retries, max_retries);
WLog_INFO(TAG, "Attempting reconnect (%u of %u)", numRetries, maxRetries);
if (freerdp_reconnect(instance))
{
xfc->disconnect = FALSE;
return TRUE;
}
sleep(5);
}
@ -1487,7 +1492,7 @@ void* xf_client_thread(void *param)
nCount += freerdp_get_event_handles(context, &handles[nCount]);
}
waitStatus = WaitForMultipleObjects(nCount, handles, FALSE, INFINITE);
waitStatus = WaitForMultipleObjects(nCount, handles, FALSE, 100);
if (!settings->AsyncTransport)
{
@ -1642,9 +1647,13 @@ static int xfreerdp_client_start(rdpContext* context)
WLog_ERR(TAG, "error: server hostname was not specified with /v:<server>[:port]");
return -1;
}
xfc->disconnect = FALSE;
xfc->thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) xf_client_thread,
context->instance, 0, NULL);
xfc->thread = CreateThread(NULL, 0,
(LPTHREAD_START_ROUTINE) xf_client_thread,
context->instance, 0, NULL);
return 0;
}
@ -1654,8 +1663,10 @@ static int xfreerdp_client_stop(rdpContext* context)
if (context->settings->AsyncInput)
{
wMessageQueue *queue;
wMessageQueue* queue;
queue = freerdp_get_message_queue(context->instance, FREERDP_INPUT_MESSAGE_QUEUE);
if (queue)
MessageQueue_PostQuit(queue, 0);
}
@ -1666,6 +1677,7 @@ static int xfreerdp_client_stop(rdpContext* context)
if (xfc->thread)
{
WaitForSingleObject(xfc->thread, INFINITE);
CloseHandle(xfc->thread);
xfc->thread = NULL;
}
@ -1706,26 +1718,45 @@ static void xfreerdp_client_free(freerdp* instance, rdpContext* context)
{
xfContext* xfc = (xfContext*) context;
if (context)
if (!context)
return;
xf_window_free(xfc);
if (xfc->bitmap_buffer)
{
xf_window_free(xfc);
if (xfc->bitmap_buffer)
_aligned_free(xfc->bitmap_buffer);
if (xfc->display)
XCloseDisplay(xfc->display);
if (xfc->x11event)
CloseHandle(xfc->x11event);
if (context->channels)
{
freerdp_channels_close(context->channels, instance);
freerdp_channels_free(context->channels);
context->channels = NULL;
}
_aligned_free(xfc->bitmap_buffer);
xfc->bitmap_buffer = NULL;
}
if (xfc->display)
{
XCloseDisplay(xfc->display);
xfc->display = NULL;
}
if (xfc->x11event)
{
CloseHandle(xfc->x11event);
xfc->x11event = NULL;
}
if (context->channels)
{
freerdp_channels_close(context->channels, instance);
freerdp_channels_free(context->channels);
context->channels = NULL;
}
if (xfc->mutex)
{
WaitForSingleObject(xfc->mutex, INFINITE);
CloseHandle(xfc->mutex);
xfc->mutex = NULL;
}
xf_monitors_free(xfc, instance->settings);
gdi_free(instance);
}
int RdpClientEntry(RDP_CLIENT_ENTRY_POINTS* pEntryPoints)

View File

@ -890,7 +890,4 @@ void xf_graphics_pipeline_init(xfContext* xfc, RdpgfxClientContext* gfx)
void xf_graphics_pipeline_uninit(xfContext* xfc, RdpgfxClientContext* gfx)
{
region16_uninit(&(xfc->invalidRegion));
gfx->custom = NULL;
xfc->gfx = NULL;
}

View File

@ -62,8 +62,8 @@
BOOL freerdp_connect(freerdp* instance)
{
rdpRdp* rdp;
BOOL status = TRUE;
rdpSettings* settings;
BOOL status = FALSE;
ConnectionResultEventArgs e;
/* We always set the return code to 0 before we start the connect sequence*/
@ -73,7 +73,10 @@ BOOL freerdp_connect(freerdp* instance)
rdp = instance->context->rdp;
settings = instance->settings;
IFCALLRET(instance->PreConnect, status, instance);
if (!rdp->reconnect)
{
IFCALLRET(instance->PreConnect, status, instance);
}
if (settings->KeyboardLayout == KBD_JAPANESE_INPUT_SYSTEM_MS_IME2002)
{
@ -116,7 +119,11 @@ BOOL freerdp_connect(freerdp* instance)
instance->update->dump_rfx = TRUE;
}
IFCALLRET(instance->PostConnect, status, instance);
if (!rdp->reconnect)
{
IFCALLRET(instance->PostConnect, status, instance);
}
update_post_connect(instance->update);
if (!status)
@ -345,9 +352,14 @@ BOOL freerdp_disconnect(freerdp* instance)
rdpRdp* rdp;
rdp = instance->context->rdp;
rdp_client_disconnect(rdp);
update_post_disconnect(instance->update);
IFCALL(instance->PostDisconnect, instance);
if (!rdp->reconnect)
{
IFCALL(instance->PostDisconnect, instance);
}
if (instance->update->pcap_rfx)
{
@ -361,8 +373,19 @@ BOOL freerdp_disconnect(freerdp* instance)
BOOL freerdp_reconnect(freerdp* instance)
{
freerdp_disconnect(instance);
return freerdp_connect(instance);
BOOL status = TRUE;
rdpRdp* rdp = instance->context->rdp;
rdp->reconnect = TRUE;
status = freerdp_disconnect(instance);
if (status)
status = freerdp_connect(instance);
rdp->reconnect = FALSE;
return status;
}
BOOL freerdp_shall_disconnect(freerdp* instance)

View File

@ -169,6 +169,7 @@ struct rdp_rdp
BYTE fips_decrypt_key[24];
UINT32 errorInfo;
UINT32 finalize_sc_pdus;
BOOL reconnect;
BOOL disconnect;
BOOL resendFocus;
BOOL deactivation_reactivation;

View File

@ -582,6 +582,7 @@ BOOL tls_prepare(rdpTls* tls, BIO *underlying, const SSL_METHOD *method, int opt
#endif
{
tls->ctx = SSL_CTX_new(method);
if (!tls->ctx)
{
WLog_ERR(TAG, "SSL_CTX_new failed");
@ -593,8 +594,10 @@ BOOL tls_prepare(rdpTls* tls, BIO *underlying, const SSL_METHOD *method, int opt
SSL_CTX_set_options(tls->ctx, options);
SSL_CTX_set_read_ahead(tls->ctx, 1);
if (tls->settings->PermittedTLSCiphers) {
if(!SSL_CTX_set_cipher_list(tls->ctx, tls->settings->PermittedTLSCiphers)) {
if (tls->settings->PermittedTLSCiphers)
{
if (!SSL_CTX_set_cipher_list(tls->ctx, tls->settings->PermittedTLSCiphers))
{
WLog_ERR(TAG, "SSL_CTX_set_cipher_list %s failed", tls->settings->PermittedTLSCiphers);
return FALSE;
}
@ -755,8 +758,6 @@ int tls_connect(rdpTls* tls, BIO *underlying)
return tls_do_handshake(tls, TRUE);
}
BOOL tls_accept(rdpTls* tls, BIO *underlying, const char* cert_file, const char* privatekey_file)
{
long options = 0;
@ -1392,6 +1393,12 @@ void tls_free(rdpTls* tls)
tls->ctx = NULL;
}
if (tls->bio)
{
BIO_free(tls->bio);
tls->bio = NULL;
}
if (tls->PublicKey)
{
free(tls->PublicKey);