Merge pull request #1664 from vworkspace/auto-reconnect
Addition of auto reconnect to FreeRDP core and X11 client
This commit is contained in:
commit
ae9c10e233
@ -51,6 +51,8 @@
|
||||
#include <X11/extensions/Xrender.h>
|
||||
#endif
|
||||
|
||||
#define WITH_AUTORECONNECT
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@ -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,
|
||||
@ -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;
|
||||
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -41,6 +41,9 @@
|
||||
#include <net/if.h>
|
||||
|
||||
#ifdef __APPLE__
|
||||
#ifndef SOL_TCP
|
||||
#define SOL_TCP IPPROTO_TCP
|
||||
#endif
|
||||
#ifndef TCP_KEEPIDLE
|
||||
#define TCP_KEEPIDLE TCP_KEEPALIVE
|
||||
#endif
|
||||
@ -251,7 +254,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
|
||||
|
@ -49,6 +49,8 @@ static void fatal_handler(int signum)
|
||||
struct sigaction default_sigaction;
|
||||
sigset_t this_mask;
|
||||
|
||||
printf("fatal_handler: signum=%d\n", signum);
|
||||
|
||||
if (terminal_needs_reset)
|
||||
tcsetattr(terminal_fildes, TCSAFLUSH, &orig_flags);
|
||||
|
||||
@ -74,7 +76,6 @@ const int fatal_signals[] =
|
||||
SIGILL,
|
||||
SIGINT,
|
||||
SIGKILL,
|
||||
SIGPIPE,
|
||||
SIGQUIT,
|
||||
SIGSEGV,
|
||||
SIGSTOP,
|
||||
@ -128,6 +129,9 @@ int freerdp_handle_signals(void)
|
||||
|
||||
pthread_sigmask(SIG_SETMASK, &orig_set, NULL);
|
||||
|
||||
/* Ignore SIGPIPE signal. */
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user