diff --git a/src/protocols/rdp/rdp.c b/src/protocols/rdp/rdp.c index 0b15d055..f21e30c5 100644 --- a/src/protocols/rdp/rdp.c +++ b/src/protocols/rdp/rdp.c @@ -763,21 +763,14 @@ static int guac_rdp_handle_connection(guac_client* client) { pthread_mutex_lock(&(rdp_client->rdp_lock)); /* Check the libfreerdp fds */ - if (!freerdp_check_fds(rdp_inst)) { - guac_client_abort(client, - GUAC_PROTOCOL_STATUS_UPSTREAM_UNAVAILABLE, - "Error handling RDP file descriptors"); - pthread_mutex_unlock(&(rdp_client->rdp_lock)); - return 1; - } + if (!freerdp_check_fds(rdp_inst) + || !freerdp_channels_check_fds(channels, rdp_inst)) { - /* Check channel fds */ - if (!freerdp_channels_check_fds(channels, rdp_inst)) { - guac_client_abort(client, - GUAC_PROTOCOL_STATUS_UPSTREAM_UNAVAILABLE, - "Error handling RDP channel file descriptors"); + /* Flag connection failure */ + wait_result = -1; pthread_mutex_unlock(&(rdp_client->rdp_lock)); - return 1; + break; + } /* Check for channel events */ @@ -801,13 +794,6 @@ static int guac_rdp_handle_connection(guac_client* client) { } - /* Handle RDP disconnect */ - if (freerdp_shall_disconnect(rdp_inst)) { - guac_rdp_client_abort(client); - pthread_mutex_unlock(&(rdp_client->rdp_lock)); - return 1; - } - pthread_mutex_unlock(&(rdp_client->rdp_lock)); /* Calculate time remaining in frame */ @@ -841,15 +827,26 @@ static int guac_rdp_handle_connection(guac_client* client) { } - /* If an error occurred, fail */ - if (wait_result < 0) + /* Test whether the RDP server is closing the connection */ + pthread_mutex_lock(&(rdp_client->rdp_lock)); + int connection_closing = freerdp_shall_disconnect(rdp_inst); + pthread_mutex_unlock(&(rdp_client->rdp_lock)); + + /* Close connection cleanly if server is disconnecting */ + if (connection_closing) + guac_rdp_client_abort(client); + + /* If a low-level connection error occurred, fail */ + else if (wait_result < 0) guac_client_abort(client, GUAC_PROTOCOL_STATUS_UPSTREAM_UNAVAILABLE, "Connection closed."); - /* Flush frame */ - guac_common_display_flush(rdp_client->display); - guac_client_end_frame(client); - guac_socket_flush(client->socket); + /* Flush frame only if successful */ + else { + guac_common_display_flush(rdp_client->display); + guac_client_end_frame(client); + guac_socket_flush(client->socket); + } }