diff options
author | Karl Mikaelsson <derfian@cendio.se> | 2018-03-23 15:52:50 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-03-23 15:52:50 +0100 |
commit | a0bf290ea2b8940e06494bd9da54a1f9a7db7940 (patch) | |
tree | f596783194f34ef46607e437928d78d6c94e0b6d | |
parent | 8346fea6cc42e405aaad94d22c305949c201a288 (diff) | |
parent | 5c48d5d788e5cfd64c2d3d535b2387a53472a068 (diff) | |
download | rdesktop-a0bf290ea2b8940e06494bd9da54a1f9a7db7940.zip |
Merge pull request #252 from rdesktop/revert-249-reconnect-related-fixes
Revert "Reconnect-related fixes"
-rw-r--r-- | rdesktop.c | 73 | ||||
-rw-r--r-- | tcp.c | 142 |
2 files changed, 66 insertions, 149 deletions
@@ -1395,55 +1395,54 @@ main(int argc, char *argv[]) deactivated = False; g_reconnect_loop = False; + ext_disc_reason = 0; rdp_main_loop(&deactivated, &ext_disc_reason); tcp_run_ui(False); + + logger(Core, Verbose, "Disconnecting..."); rdp_disconnect(); - if (deactivated) + /* If error info is set we do want to exit rdesktop + connect loop. We do this by clearing flags that + triggers a reconnect that could be set elsewere */ + if (ext_disc_reason != 0) { - /* Server disconnected while deactivated */ - logger(Core, Notice, "Disconnecting..."); - break; + g_redirect = False; + g_network_error = False; + g_pending_resize = False; } - else + + if (g_redirect) + continue; + + /* handle network error and start autoreconnect */ + if (g_network_error && !deactivated) { - /* Unexpected disconnect or rdesktop-initiated loop exit */ + logger(Core, Notice, + "Disconnected due to network error, retrying to reconnect for %d minutes.", + RECONNECT_TIMEOUT / 60); + g_network_error = False; + g_reconnect_loop = True; + continue; + } - if (g_user_quit) - { - /* User closed window */ - break; - } - else if (g_redirect) - { - /* see beginning of loop */ - } - else if (g_network_error) - { - logger(Core, Notice, - "Disconnected due to network error, retrying to reconnect for %d minutes.", - RECONNECT_TIMEOUT / 60); - g_network_error = False; - g_reconnect_loop = True; - } - else if (g_pending_resize) - { - /* Prepare to re-create rdesktop window */ - ui_seamless_end(); - ui_destroy_window(); - - logger(Core, Verbose, "Resize reconnect loop triggered, new size %dx%d", - g_requested_session_width, g_requested_session_height); - g_pending_resize = False; - g_reconnect_loop = True; - } + ui_seamless_end(); + ui_destroy_window(); + + /* Enter a reconnect loop if we have a pending resize request */ + if (g_pending_resize) + { + logger(Core, Verbose, "Resize reconnect loop triggered, new size %dx%d", + g_requested_session_width, g_requested_session_height); + g_pending_resize = False; + g_reconnect_loop = True; continue; } - } - ui_seamless_end(); - ui_destroy_window(); + /* exit main reconnect loop */ + break; + } cache_save_state(); ui_deinit(); @@ -58,13 +58,6 @@ #define STREAM_COUNT 1 #endif -#ifdef IPv6 -static struct addrinfo *g_server_address = NULL; -#else -struct sockaddr_in *g_server_address = NULL; -#endif - -static char *g_last_server_name = NULL; static RD_BOOL g_ssl_initialized = False; static SSL *g_ssl = NULL; static SSL_CTX *g_ssl_ctx = NULL; @@ -423,85 +416,47 @@ tcp_tls_get_server_pubkey(STREAM s) return (s->size != 0); } -/* Helper function to determine if rdesktop should resolve hostnames again or not */ -static RD_BOOL -tcp_connect_resolve_hostname(const char *server) -{ - return (g_server_address == NULL || - g_last_server_name == NULL || - strcmp(g_last_server_name, server) != 0); -} - -/* Establish a connection on the TCP layer - - This function tries to avoid resolving any server address twice. The - official Windows 2008 documentation states that the windows farm name - should be a round-robin DNS entry containing all the terminal servers - in the farm. When connected to the farm address, if we look up the - address again when reconnecting (for any reason) we risk reconnecting - to a different server in the farm. -*/ - +/* Establish a connection on the TCP layer */ RD_BOOL tcp_connect(char *server) { socklen_t option_len; uint32 option_value; int i; - char buf[NI_MAXHOST]; #ifdef IPv6 int n; - struct addrinfo hints, *res, *addr; - struct sockaddr *oldaddr; + struct addrinfo hints, *res, *ressave; char tcp_port_rdp_s[10]; - if (tcp_connect_resolve_hostname(server)) - { - snprintf(tcp_port_rdp_s, 10, "%d", g_tcp_port_rdp); + snprintf(tcp_port_rdp_s, 10, "%d", g_tcp_port_rdp); - memset(&hints, 0, sizeof(struct addrinfo)); - hints.ai_family = AF_UNSPEC; - hints.ai_socktype = SOCK_STREAM; + memset(&hints, 0, sizeof(struct addrinfo)); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; - if ((n = getaddrinfo(server, tcp_port_rdp_s, &hints, &res))) - { - logger(Core, Error, "tcp_connect(), getaddrinfo() failed: %s", gai_strerror(n)); - return False; - } - } - else + if ((n = getaddrinfo(server, tcp_port_rdp_s, &hints, &res))) { - res = g_server_address; + logger(Core, Error, "tcp_connect(), getaddrinfo() failed: %s", gai_strerror(n)); + return False; } + ressave = res; g_sock = -1; - - for (addr = res; addr != NULL; addr = addr->ai_next) + while (res) { - g_sock = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol); - if (g_sock < 0) - { - logger(Core, Debug, "tcp_connect(), socket() failed: %s", TCP_STRERROR); - continue; - } - - n = getnameinfo(addr->ai_addr, addr->ai_addrlen, buf, sizeof(buf), NULL, 0, NI_NUMERICHOST); - if (n != 0) + g_sock = socket(res->ai_family, res->ai_socktype, res->ai_protocol); + if (!(g_sock < 0)) { - logger(Core, Error, "tcp_connect(), getnameinfo() failed: %s", gai_strerror(n)); - return False; + if (connect(g_sock, res->ai_addr, res->ai_addrlen) == 0) + break; + TCP_CLOSE(g_sock); + g_sock = -1; } - - logger(Core, Debug, "tcp_connect(), trying %s (%s)", server, buf); - - if (connect(g_sock, addr->ai_addr, addr->ai_addrlen) == 0) - break; - - TCP_CLOSE(g_sock); - g_sock = -1; + res = res->ai_next; } + freeaddrinfo(ressave); if (g_sock == -1) { @@ -509,50 +464,19 @@ tcp_connect(char *server) return False; } - /* Save server address for later use, if we haven't already. */ +#else /* no IPv6 support */ - if (g_server_address == NULL) - { - g_server_address = xmalloc(sizeof(struct addrinfo)); - g_server_address->ai_addr = xmalloc(sizeof(struct sockaddr_storage)); - } + struct hostent *nslookup; + struct sockaddr_in servaddr; - if (g_server_address != addr) + if ((nslookup = gethostbyname(server)) != NULL) { - /* don't overwrite ptr to allocated sockaddr */ - oldaddr = g_server_address->ai_addr; - memcpy(g_server_address, addr, sizeof(struct addrinfo)); - g_server_address->ai_addr = oldaddr; - - memcpy(g_server_address->ai_addr, addr->ai_addr, addr->ai_addrlen); - - g_server_address->ai_canonname = NULL; - g_server_address->ai_next = NULL; - - freeaddrinfo(res); + memcpy(&servaddr.sin_addr, nslookup->h_addr, sizeof(servaddr.sin_addr)); } - -#else /* no IPv6 support */ - struct hostent *nslookup = NULL; - - if (tcp_connect_resolve_hostname(server)) + else if ((servaddr.sin_addr.s_addr = inet_addr(server)) == INADDR_NONE) { - if (g_server_address != NULL) - xfree(g_server_address); - g_server_address = xmalloc(sizeof(struct sockaddr_in)); - g_server_address->sin_family = AF_INET; - g_server_address->sin_port = htons((uint16) g_tcp_port_rdp); - - if ((nslookup = gethostbyname(server)) != NULL) - { - memcpy(&g_server_address->sin_addr, nslookup->h_addr, - sizeof(g_server_address->sin_addr)); - } - else if ((g_server_address->sin_addr.s_addr = inet_addr(server)) == INADDR_NONE) - { - logger(Core, Error, "tcp_connect(), unable to resolve host '%s'", server); - return False; - } + logger(Core, Error, "tcp_connect(), unable to resolve host '%s'", server); + return False; } if ((g_sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) @@ -561,12 +485,10 @@ tcp_connect(char *server) return False; } - logger(Core, Debug, "tcp_connect(), trying %s (%s)", - server, inet_ntop(g_server_address->sin_family, - &g_server_address->sin_addr, - buf, sizeof(buf))); + servaddr.sin_family = AF_INET; + servaddr.sin_port = htons((uint16) g_tcp_port_rdp); - if (connect(g_sock, (struct sockaddr *) g_server_address, sizeof(struct sockaddr)) < 0) + if (connect(g_sock, (struct sockaddr *) &servaddr, sizeof(struct sockaddr)) < 0) { if (!g_reconnect_loop) logger(Core, Error, "tcp_connect(), connect() failed: %s", TCP_STRERROR); @@ -602,10 +524,6 @@ tcp_connect(char *server) g_out[i].data = (uint8 *) xmalloc(g_out[i].size); } - /* After successful connect: update the last server name */ - if (g_last_server_name) - xfree(g_last_server_name); - g_last_server_name = strdup(server); return True; } |