Skip to content

Commit

Permalink
Added auto reconnect to FreeRDP core and X11 client
Browse files Browse the repository at this point in the history
  • Loading branch information
vworkspace committed Jan 16, 2014
1 parent 3d75db0 commit c4f6dcc
Show file tree
Hide file tree
Showing 6 changed files with 112 additions and 1 deletion.
55 changes: 55 additions & 0 deletions client/X11/xf_client.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@
#include <X11/extensions/Xrender.h>
#endif

#define WITH_AUTORECONNECT

#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
Expand Down Expand Up @@ -1336,6 +1338,51 @@ void* xf_channels_thread(void* arg)
return NULL;
}

#ifdef WITH_AUTORECONNECT
BOOL xf_auto_reconnect(freerdp* instance)
{
xfContext* xfc = (xfContext*)instance->context;

UINT32 num_retries = 0;
UINT32 max_retries = instance->settings->AutoReconnectMaxRetries;

/* Only auto reconnect on network disconnects. */
if (freerdp_error_info(instance) != 0) return FALSE;

/* A network disconnect was detected */
fprintf(stderr, "Network disconnect!\n");
if (!instance->settings->AutoReconnectionEnabled)
{
/* No auto-reconnect - just quit */
return FALSE;
}

/* Perform an auto-reconnect. */
for (;;)
{
/* Quit retrying if max retries has been exceeded */
if (num_retries++ >= max_retries)
{
return FALSE;
}

/* Attempt the next reconnect */
fprintf(stderr, "Attempting reconnect (%u of %u)\n", num_retries, max_retries);
if (freerdp_reconnect(instance))
{
xfc->disconnect = FALSE;
return TRUE;
}

sleep(5);
}

fprintf(stderr, "Maximum reconnect retries exceeded\n");

return FALSE;
}
#endif

/** Main loop for the rdp connection.
* It will be run from the thread's entry point (thread_func()).
* It initiates the connection, and will continue to run until the session ends,
Expand Down Expand Up @@ -1382,6 +1429,11 @@ void* xf_thread(void* param)
ZeroMemory(wfds, sizeof(wfds));
ZeroMemory(&timeout, sizeof(struct timeval));

#ifdef WITH_AUTORECONNECT
instance->settings->AutoReconnectionEnabled = TRUE;
instance->settings->AutoReconnectMaxRetries = 20;
#endif

status = freerdp_connect(instance);

xfc = (xfContext*) instance->context;
Expand Down Expand Up @@ -1526,6 +1578,9 @@ void* xf_thread(void* param)
{
if (freerdp_check_fds(instance) != TRUE)
{
#ifdef WITH_AUTORECONNECT
if (xf_auto_reconnect(instance)) continue;
#endif
fprintf(stderr, "Failed to check FreeRDP file descriptor\n");
break;
}
Expand Down
1 change: 1 addition & 0 deletions include/freerdp/freerdp.h
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,7 @@ FREERDP_API void freerdp_context_free(freerdp* instance);
FREERDP_API BOOL freerdp_connect(freerdp* instance);
FREERDP_API BOOL freerdp_shall_disconnect(freerdp* instance);
FREERDP_API BOOL freerdp_disconnect(freerdp* instance);
FREERDP_API BOOL freerdp_reconnect(freerdp* instance);

FREERDP_API BOOL freerdp_get_fds(freerdp* instance, void** rfds, int* rcount, void** wfds, int* wcount);
FREERDP_API BOOL freerdp_check_fds(freerdp* instance);
Expand Down
27 changes: 27 additions & 0 deletions libfreerdp/core/connection.c
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,33 @@ BOOL rdp_client_redirect(rdpRdp* rdp)
return status;
}

BOOL rdp_client_reconnect(rdpRdp* rdp)
{
int i;

transport_disconnect(rdp->transport);

mcs_free(rdp->mcs);
nego_free(rdp->nego);
license_free(rdp->license);
transport_free(rdp->transport);

/* Reset virtual channel status */
for (i = 0; i < rdp->settings->ChannelCount; i++)
{
rdp->settings->ChannelDefArray[i].joined = FALSE;
}

rdp->transport = transport_new(rdp->settings);
rdp->license = license_new(rdp);
rdp->nego = nego_new(rdp->transport);
rdp->mcs = mcs_new(rdp->transport);

rdp->transport->layer = TRANSPORT_LAYER_TCP;

return rdp_client_connect(rdp);
}

static BYTE fips_ivec[8] = { 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF };

static BOOL rdp_client_establish_keys(rdpRdp* rdp)
Expand Down
1 change: 1 addition & 0 deletions libfreerdp/core/connection.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ enum CONNECTION_STATE

BOOL rdp_client_connect(rdpRdp* rdp);
BOOL rdp_client_redirect(rdpRdp* rdp);
BOOL rdp_client_reconnect(rdpRdp* rdp);
BOOL rdp_client_connect_mcs_connect_response(rdpRdp* rdp, wStream* s);
BOOL rdp_client_connect_mcs_attach_user_confirm(rdpRdp* rdp, wStream* s);
BOOL rdp_client_connect_mcs_channel_join_confirm(rdpRdp* rdp, wStream* s);
Expand Down
5 changes: 5 additions & 0 deletions libfreerdp/core/freerdp.c
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,11 @@ BOOL freerdp_disconnect(freerdp* instance)
return TRUE;
}

BOOL freerdp_reconnect(freerdp* instance)
{
return rdp_client_reconnect(instance->context->rdp);
}

BOOL freerdp_shall_disconnect(freerdp* instance)
{
return instance->context->rdp->disconnect;
Expand Down
24 changes: 23 additions & 1 deletion libfreerdp/core/tcp.c
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,29 @@ BOOL tcp_set_keep_alive_mode(rdpTcp* tcp)

if (setsockopt(tcp->sockfd, IPPROTO_TCP, TCP_KEEPIDLE, (void*) &option_value, option_len) < 0)
{
perror("setsockopt() IPPROTO_TCP, SO_KEEPIDLE:");
perror("setsockopt() IPPROTO_TCP, TCP_KEEPIDLE:");
return FALSE;
}
#endif

#ifdef TCP_KEEPCNT
option_value = 3;
option_len = sizeof(option_value);

if (setsockopt(tcp->sockfd, SOL_TCP, TCP_KEEPCNT, (void *) &option_value, option_len) < 0)
{
perror("setsockopt() SOL_TCP, TCP_KEEPCNT:");
return FALSE;
}
#endif

#ifdef TCP_KEEPINTVL
option_value = 2;
option_len = sizeof(option_value);

if (setsockopt(tcp->sockfd, SOL_TCP, TCP_KEEPINTVL, (void *) &option_value, option_len) < 0)
{
perror("setsockopt() SOL_TCP, TCP_KEEPINTVL:");
return FALSE;
}
#endif
Expand Down

0 comments on commit c4f6dcc

Please sign in to comment.