GUACAMOLE-1388: Merge ensure RDP-specific resources are cleaned up after channel disconnect.
This commit is contained in:
commit
12b8eac514
@ -546,6 +546,48 @@ static void guac_rdp_cliprdr_channel_connected(rdpContext* context,
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback which disassociates Guacamole from the CliprdrClientContext
|
||||||
|
* instance that was originally allocated by FreeRDP and is about to be
|
||||||
|
* deallocated.
|
||||||
|
*
|
||||||
|
* This function is called whenever a channel disconnects via the PubSub event
|
||||||
|
* system within FreeRDP, but only has any effect if the disconnected channel
|
||||||
|
* is the CLIPRDR channel. This specific callback is registered with the PubSub
|
||||||
|
* system of the relevant rdpContext when guac_rdp_clipboard_load_plugin() is
|
||||||
|
* called.
|
||||||
|
*
|
||||||
|
* @param context
|
||||||
|
* The rdpContext associated with the active RDP session.
|
||||||
|
*
|
||||||
|
* @param e
|
||||||
|
* Event-specific arguments, mainly the name of the channel, and a
|
||||||
|
* reference to the associated plugin loaded for that channel by FreeRDP.
|
||||||
|
*/
|
||||||
|
static void guac_rdp_cliprdr_channel_disconnected(rdpContext* context,
|
||||||
|
ChannelDisconnectedEventArgs* e) {
|
||||||
|
|
||||||
|
guac_client* client = ((rdp_freerdp_context*) context)->client;
|
||||||
|
guac_rdp_client* rdp_client = (guac_rdp_client*) client->data;
|
||||||
|
guac_rdp_clipboard* clipboard = rdp_client->clipboard;
|
||||||
|
|
||||||
|
/* FreeRDP-specific handlers for CLIPRDR are not assigned, and thus not
|
||||||
|
* callable, until after the relevant guac_rdp_clipboard structure is
|
||||||
|
* allocated and associated with the guac_rdp_client */
|
||||||
|
assert(clipboard != NULL);
|
||||||
|
|
||||||
|
/* Ignore disconnection event if it's not for the CLIPRDR channel */
|
||||||
|
if (strcmp(e->name, CLIPRDR_SVC_CHANNEL_NAME) != 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Channel is no longer connected */
|
||||||
|
clipboard->cliprdr = NULL;
|
||||||
|
|
||||||
|
guac_client_log(client, GUAC_LOG_DEBUG, "CLIPRDR (clipboard redirection) "
|
||||||
|
"channel disconnected.");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
guac_rdp_clipboard* guac_rdp_clipboard_alloc(guac_client* client) {
|
guac_rdp_clipboard* guac_rdp_clipboard_alloc(guac_client* client) {
|
||||||
|
|
||||||
/* Allocate clipboard and underlying storage */
|
/* Allocate clipboard and underlying storage */
|
||||||
@ -575,6 +617,10 @@ void guac_rdp_clipboard_load_plugin(guac_rdp_clipboard* clipboard,
|
|||||||
PubSub_SubscribeChannelConnected(context->pubSub,
|
PubSub_SubscribeChannelConnected(context->pubSub,
|
||||||
(pChannelConnectedEventHandler) guac_rdp_cliprdr_channel_connected);
|
(pChannelConnectedEventHandler) guac_rdp_cliprdr_channel_connected);
|
||||||
|
|
||||||
|
/* Clean up any RDP-specific resources when channel is disconnected */
|
||||||
|
PubSub_SubscribeChannelDisconnected(context->pubSub,
|
||||||
|
(pChannelDisconnectedEventHandler) guac_rdp_cliprdr_channel_disconnected);
|
||||||
|
|
||||||
guac_client_log(clipboard->client, GUAC_LOG_DEBUG, "Support for CLIPRDR "
|
guac_client_log(clipboard->client, GUAC_LOG_DEBUG, "Support for CLIPRDR "
|
||||||
"(clipboard redirection) registered. Awaiting channel "
|
"(clipboard redirection) registered. Awaiting channel "
|
||||||
"connection.");
|
"connection.");
|
||||||
|
@ -96,12 +96,52 @@ static void guac_rdp_disp_channel_connected(rdpContext* context,
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback which disassociates Guacamole from the DispClientContext instance
|
||||||
|
* that was originally allocated by FreeRDP and is about to be deallocated.
|
||||||
|
*
|
||||||
|
* This function is called whenever a channel disconnects via the PubSub event
|
||||||
|
* system within FreeRDP, but only has any effect if the disconnected channel
|
||||||
|
* is the Display Update channel. This specific callback is registered with the
|
||||||
|
* PubSub system of the relevant rdpContext when guac_rdp_disp_load_plugin() is
|
||||||
|
* called.
|
||||||
|
*
|
||||||
|
* @param context
|
||||||
|
* The rdpContext associated with the active RDP session.
|
||||||
|
*
|
||||||
|
* @param e
|
||||||
|
* Event-specific arguments, mainly the name of the channel, and a
|
||||||
|
* reference to the associated plugin loaded for that channel by FreeRDP.
|
||||||
|
*/
|
||||||
|
static void guac_rdp_disp_channel_disconnected(rdpContext* context,
|
||||||
|
ChannelDisconnectedEventArgs* e) {
|
||||||
|
|
||||||
|
guac_client* client = ((rdp_freerdp_context*) context)->client;
|
||||||
|
guac_rdp_client* rdp_client = (guac_rdp_client*) client->data;
|
||||||
|
guac_rdp_disp* guac_disp = rdp_client->disp;
|
||||||
|
|
||||||
|
/* Ignore disconnection event if it's not for the Display Update channel */
|
||||||
|
if (strcmp(e->name, DISP_DVC_CHANNEL_NAME) != 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Channel is no longer connected */
|
||||||
|
guac_disp->disp = NULL;
|
||||||
|
|
||||||
|
guac_client_log(client, GUAC_LOG_DEBUG, "Display update channel "
|
||||||
|
"disconnected.");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void guac_rdp_disp_load_plugin(rdpContext* context) {
|
void guac_rdp_disp_load_plugin(rdpContext* context) {
|
||||||
|
|
||||||
/* Subscribe to and handle channel connected events */
|
/* Subscribe to and handle channel connected events */
|
||||||
PubSub_SubscribeChannelConnected(context->pubSub,
|
PubSub_SubscribeChannelConnected(context->pubSub,
|
||||||
(pChannelConnectedEventHandler) guac_rdp_disp_channel_connected);
|
(pChannelConnectedEventHandler) guac_rdp_disp_channel_connected);
|
||||||
|
|
||||||
|
/* Subscribe to and handle channel disconnected events */
|
||||||
|
PubSub_SubscribeChannelDisconnected(context->pubSub,
|
||||||
|
(pChannelDisconnectedEventHandler) guac_rdp_disp_channel_disconnected);
|
||||||
|
|
||||||
/* Add "disp" channel */
|
/* Add "disp" channel */
|
||||||
guac_freerdp_dynamic_channel_collection_add(context->settings, "disp", NULL);
|
guac_freerdp_dynamic_channel_collection_add(context->settings, "disp", NULL);
|
||||||
|
|
||||||
|
@ -94,12 +94,51 @@ static void guac_rdp_rdpei_channel_connected(rdpContext* context,
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback which disassociates Guacamole from the RdpeiClientContext instance
|
||||||
|
* that was originally allocated by FreeRDP and is about to be deallocated.
|
||||||
|
*
|
||||||
|
* This function is called whenever a channel disconnects via the PubSub event
|
||||||
|
* system within FreeRDP, but only has any effect if the disconnected channel
|
||||||
|
* is the RDPEI channel. This specific callback is registered with the PubSub
|
||||||
|
* system of the relevant rdpContext when guac_rdp_rdpei_load_plugin() is
|
||||||
|
* called.
|
||||||
|
*
|
||||||
|
* @param context
|
||||||
|
* The rdpContext associated with the active RDP session.
|
||||||
|
*
|
||||||
|
* @param e
|
||||||
|
* Event-specific arguments, mainly the name of the channel, and a
|
||||||
|
* reference to the associated plugin loaded for that channel by FreeRDP.
|
||||||
|
*/
|
||||||
|
static void guac_rdp_rdpei_channel_disconnected(rdpContext* context,
|
||||||
|
ChannelDisconnectedEventArgs* e) {
|
||||||
|
|
||||||
|
guac_client* client = ((rdp_freerdp_context*) context)->client;
|
||||||
|
guac_rdp_client* rdp_client = (guac_rdp_client*) client->data;
|
||||||
|
guac_rdp_rdpei* guac_rdpei = rdp_client->rdpei;
|
||||||
|
|
||||||
|
/* Ignore disconnection event if it's not for the RDPEI channel */
|
||||||
|
if (strcmp(e->name, RDPEI_DVC_CHANNEL_NAME) != 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Channel is no longer connected */
|
||||||
|
guac_rdpei->rdpei = NULL;
|
||||||
|
|
||||||
|
guac_client_log(client, GUAC_LOG_DEBUG, "RDPDI channel disconnected.");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void guac_rdp_rdpei_load_plugin(rdpContext* context) {
|
void guac_rdp_rdpei_load_plugin(rdpContext* context) {
|
||||||
|
|
||||||
/* Subscribe to and handle channel connected events */
|
/* Subscribe to and handle channel connected events */
|
||||||
PubSub_SubscribeChannelConnected(context->pubSub,
|
PubSub_SubscribeChannelConnected(context->pubSub,
|
||||||
(pChannelConnectedEventHandler) guac_rdp_rdpei_channel_connected);
|
(pChannelConnectedEventHandler) guac_rdp_rdpei_channel_connected);
|
||||||
|
|
||||||
|
/* Subscribe to and handle channel disconnected events */
|
||||||
|
PubSub_SubscribeChannelDisconnected(context->pubSub,
|
||||||
|
(pChannelDisconnectedEventHandler) guac_rdp_rdpei_channel_disconnected);
|
||||||
|
|
||||||
/* Add "rdpei" channel */
|
/* Add "rdpei" channel */
|
||||||
guac_freerdp_dynamic_channel_collection_add(context->settings, "rdpei", NULL);
|
guac_freerdp_dynamic_channel_collection_add(context->settings, "rdpei", NULL);
|
||||||
|
|
||||||
|
@ -471,18 +471,6 @@ static int guac_rdp_handle_connection(guac_client* client) {
|
|||||||
|
|
||||||
pthread_rwlock_wrlock(&(rdp_client->lock));
|
pthread_rwlock_wrlock(&(rdp_client->lock));
|
||||||
|
|
||||||
/* Set up screen recording, if requested */
|
|
||||||
if (settings->recording_path != NULL) {
|
|
||||||
rdp_client->recording = guac_common_recording_create(client,
|
|
||||||
settings->recording_path,
|
|
||||||
settings->recording_name,
|
|
||||||
settings->create_recording_path,
|
|
||||||
!settings->recording_exclude_output,
|
|
||||||
!settings->recording_exclude_mouse,
|
|
||||||
!settings->recording_exclude_touch,
|
|
||||||
settings->recording_include_keys);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Create display */
|
/* Create display */
|
||||||
rdp_client->display = guac_common_display_alloc(client,
|
rdp_client->display = guac_common_display_alloc(client,
|
||||||
rdp_client->settings->width,
|
rdp_client->settings->width,
|
||||||
@ -816,6 +804,18 @@ void* guac_rdp_client_thread(void* data) {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Set up screen recording, if requested */
|
||||||
|
if (settings->recording_path != NULL) {
|
||||||
|
rdp_client->recording = guac_common_recording_create(client,
|
||||||
|
settings->recording_path,
|
||||||
|
settings->recording_name,
|
||||||
|
settings->create_recording_path,
|
||||||
|
!settings->recording_exclude_output,
|
||||||
|
!settings->recording_exclude_mouse,
|
||||||
|
!settings->recording_exclude_touch,
|
||||||
|
settings->recording_include_keys);
|
||||||
|
}
|
||||||
|
|
||||||
/* Continue handling connections until error or client disconnect */
|
/* Continue handling connections until error or client disconnect */
|
||||||
while (client->state == GUAC_CLIENT_RUNNING) {
|
while (client->state == GUAC_CLIENT_RUNNING) {
|
||||||
if (guac_rdp_handle_connection(client))
|
if (guac_rdp_handle_connection(client))
|
||||||
|
Loading…
Reference in New Issue
Block a user