summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKarl Mikaelsson <derfian@cendio.se>2018-03-23 15:52:50 +0100
committerGitHub <noreply@github.com>2018-03-23 15:52:50 +0100
commita0bf290ea2b8940e06494bd9da54a1f9a7db7940 (patch)
treef596783194f34ef46607e437928d78d6c94e0b6d
parent8346fea6cc42e405aaad94d22c305949c201a288 (diff)
parent5c48d5d788e5cfd64c2d3d535b2387a53472a068 (diff)
downloadrdesktop-a0bf290ea2b8940e06494bd9da54a1f9a7db7940.zip
Merge pull request #252 from rdesktop/revert-249-reconnect-related-fixes
Revert "Reconnect-related fixes"
-rw-r--r--rdesktop.c73
-rw-r--r--tcp.c142
2 files changed, 66 insertions, 149 deletions
diff --git a/rdesktop.c b/rdesktop.c
index cb5e4b1..522eaff 100644
--- a/rdesktop.c
+++ b/rdesktop.c
@@ -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();
diff --git a/tcp.c b/tcp.c
index 979feae..0cbb0ec 100644
--- a/tcp.c
+++ b/tcp.c
@@ -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;
}