Reconnect upon network failure, retry as long the autoreconnect

cookie is valid.



git-svn-id: svn://svn.code.sf.net/p/rdesktop/code/rdesktop/trunk@1707 423420c4-83ab-492f-b58f-81f9feb106b5
This commit is contained in:
Henrik Andersson 2013-04-12 06:46:07 +00:00
parent da3dcb8fbe
commit eced6ca821
5 changed files with 66 additions and 4 deletions

View File

@ -268,6 +268,7 @@ void ui_deinit(void);
RD_BOOL ui_create_window(void); RD_BOOL ui_create_window(void);
void ui_resize_window(void); void ui_resize_window(void);
void ui_destroy_window(void); void ui_destroy_window(void);
RD_BOOL ui_have_window(void);
void xwin_toggle_fullscreen(void); void xwin_toggle_fullscreen(void);
int ui_select(int rdp_socket); int ui_select(int rdp_socket);
void ui_move_pointer(int x, int y); void ui_move_pointer(int x, int y);

View File

@ -80,6 +80,7 @@ int g_pos = 0; /* 0 position unspecified,
extern int g_tcp_port_rdp; extern int g_tcp_port_rdp;
int g_server_depth = -1; int g_server_depth = -1;
int g_win_button_size = 0; /* If zero, disable single app mode */ int g_win_button_size = 0; /* If zero, disable single app mode */
RD_BOOL g_network_error = False;
RD_BOOL g_bitmap_compression = True; RD_BOOL g_bitmap_compression = True;
RD_BOOL g_sendmotion = True; RD_BOOL g_sendmotion = True;
RD_BOOL g_bitmap_cache = True; RD_BOOL g_bitmap_cache = True;
@ -119,6 +120,7 @@ uint32 g_redirect_flags = 0;
uint32 g_reconnect_logonid = 0; uint32 g_reconnect_logonid = 0;
char g_reconnect_random[16]; char g_reconnect_random[16];
time_t g_reconnect_random_ts;
RD_BOOL g_has_reconnect_random = False; RD_BOOL g_has_reconnect_random = 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;
@ -489,6 +491,7 @@ main(int argc, char *argv[])
char password[64]; char password[64];
char shell[256]; char shell[256];
char directory[256]; char directory[256];
RD_BOOL reconnect_loop;
RD_BOOL prompt_password, deactivated; RD_BOOL prompt_password, deactivated;
struct passwd *pw; struct passwd *pw;
uint32 flags, ext_disc_reason = 0; uint32 flags, ext_disc_reason = 0;
@ -1066,7 +1069,7 @@ main(int argc, char *argv[])
lspci_init(); lspci_init();
rdpdr_init(); rdpdr_init();
reconnect_loop = False;
while (1) while (1)
{ {
rdesktop_reset_state(); rdesktop_reset_state();
@ -1084,7 +1087,21 @@ main(int argc, char *argv[])
ui_init_connection(); ui_init_connection();
if (!rdp_connect(server, flags, domain, password, shell, directory, g_redirect)) if (!rdp_connect(server, flags, domain, password, shell, directory, g_redirect))
return EX_PROTOCOL; {
g_network_error = False;
if (reconnect_loop == False)
return EX_PROTOCOL;
/* check if auto reconnect cookie has timed out */
if (time(NULL) - g_reconnect_random_ts > (3600 + 600))
return EX_PROTOCOL;
fprintf(stderr, "Failed to connect, retry in 4 secs...\n");
sleep(4);
continue;
}
/* By setting encryption to False here, we have an encrypted login /* By setting encryption to False here, we have an encrypted login
packet but unencrypted transfer of other packets */ packet but unencrypted transfer of other packets */
@ -1095,11 +1112,15 @@ main(int argc, char *argv[])
DEBUG(("Connection successful.\n")); DEBUG(("Connection successful.\n"));
memset(password, 0, sizeof(password)); memset(password, 0, sizeof(password));
if (!g_redirect) /* only create a window if we dont have one intialized */
if (!ui_have_window())
{
if (!ui_create_window()) if (!ui_create_window())
return EX_OSERR; return EX_OSERR;
}
g_redirect = False; g_redirect = False;
reconnect_loop = False;
rdp_main_loop(&deactivated, &ext_disc_reason); rdp_main_loop(&deactivated, &ext_disc_reason);
DEBUG(("Disconnecting...\n")); DEBUG(("Disconnecting...\n"));
@ -1109,12 +1130,22 @@ main(int argc, char *argv[])
if (g_redirect) if (g_redirect)
continue; continue;
/* handle network error and start autoreconnect */
if (g_network_error)
{
g_network_error = False;
reconnect_loop = True;
continue;
}
ui_seamless_end(); ui_seamless_end();
ui_destroy_window(); ui_destroy_window();
/* Enter a reconnect loop if we have a pending resize request */
if (g_pending_resize) if (g_pending_resize)
{ {
/* If we have a pending resize, reconnect using the new size, rather than exit */
g_pending_resize = False; g_pending_resize = False;
reconnect_loop = True;
continue; continue;
} }
break; break;

6
rdp.c
View File

@ -54,6 +54,7 @@ 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_network_error;
uint8 *g_next_packet; uint8 *g_next_packet;
uint32 g_rdp_shareid; uint32 g_rdp_shareid;
@ -72,6 +73,7 @@ extern uint32 g_redirect_flags;
extern uint32 g_reconnect_logonid; extern uint32 g_reconnect_logonid;
extern char g_reconnect_random[16]; extern char g_reconnect_random[16];
extern time_t g_reconnect_random_ts;
extern RD_BOOL g_has_reconnect_random; extern RD_BOOL g_has_reconnect_random;
extern uint8 g_client_random[SEC_RANDOM_SIZE]; extern uint8 g_client_random[SEC_RANDOM_SIZE];
@ -1369,6 +1371,7 @@ process_pdu_logon(STREAM s)
in_uint32_le(s, g_reconnect_logonid); in_uint32_le(s, g_reconnect_logonid);
in_uint8a(s, g_reconnect_random, 16); in_uint8a(s, g_reconnect_random, 16);
g_has_reconnect_random = True; g_has_reconnect_random = True;
g_reconnect_random_ts = time(NULL);
DEBUG(("Saving auto-reconnect cookie, id=%u\n", g_reconnect_logonid)); DEBUG(("Saving auto-reconnect cookie, id=%u\n", g_reconnect_logonid));
} }
} }
@ -1644,6 +1647,9 @@ rdp_connect(char *server, uint32 flags, char *domain, char *password,
/* run RDP loop until first licence demand active PDU */ /* run RDP loop until first licence demand active PDU */
while (!g_rdp_shareid) while (!g_rdp_shareid)
{ {
if (g_network_error)
return False;
if (!rdp_loop(&deactivated, &ext_disc_reason)) if (!rdp_loop(&deactivated, &ext_disc_reason))
return False; return False;
} }

18
tcp.c
View File

@ -64,6 +64,7 @@ static struct stream g_in;
static struct stream g_out[STREAM_COUNT]; static struct stream g_out[STREAM_COUNT];
int g_tcp_port_rdp = TCP_PORT_RDP; int g_tcp_port_rdp = TCP_PORT_RDP;
extern RD_BOOL g_user_quit; extern RD_BOOL g_user_quit;
extern RD_BOOL g_network_error;
/* wait till socket is ready to write or timeout */ /* wait till socket is ready to write or timeout */
static RD_BOOL static RD_BOOL
@ -140,6 +141,10 @@ tcp_send(STREAM s)
else else
{ {
error("SSL_write: %d (%s)\n", ssl_err, TCP_STRERROR); error("SSL_write: %d (%s)\n", ssl_err, TCP_STRERROR);
g_network_error = True;
#ifdef WITH_SCARD
scard_unlock(SCARD_LOCK_TCP);
#endif
return; return;
} }
} }
@ -157,6 +162,10 @@ tcp_send(STREAM s)
else else
{ {
error("send: %s\n", TCP_STRERROR); error("send: %s\n", TCP_STRERROR);
g_network_error = True;
#ifdef WITH_SCARD
scard_unlock(SCARD_LOCK_TCP);
#endif
return; return;
} }
} }
@ -224,6 +233,7 @@ tcp_recv(STREAM s, uint32 length)
} }
ERR_print_errors_fp(stdout); ERR_print_errors_fp(stdout);
g_network_error = True;
return NULL; return NULL;
} }
@ -234,6 +244,7 @@ tcp_recv(STREAM s, uint32 length)
else if (ssl_err != SSL_ERROR_NONE) else if (ssl_err != SSL_ERROR_NONE)
{ {
error("SSL_read: %d (%s)\n", ssl_err, TCP_STRERROR); error("SSL_read: %d (%s)\n", ssl_err, TCP_STRERROR);
g_network_error = True;
return NULL; return NULL;
} }
@ -250,6 +261,7 @@ tcp_recv(STREAM s, uint32 length)
else else
{ {
error("recv: %s\n", TCP_STRERROR); error("recv: %s\n", TCP_STRERROR);
g_network_error = True;
return NULL; return NULL;
} }
} }
@ -532,6 +544,12 @@ tcp_reset_state(void)
{ {
int i; int i;
if (g_ssl)
{
SSL_free(g_ssl);
g_ssl = NULL;
}
g_sock = -1; /* reset socket */ g_sock = -1; /* reset socket */
/* Clear the incoming stream */ /* Clear the incoming stream */

6
xwin.c
View File

@ -2160,6 +2160,12 @@ ui_resize_window()
} }
} }
RD_BOOL
ui_have_window()
{
return g_wnd ? True : False;
}
void void
ui_destroy_window(void) ui_destroy_window(void)
{ {