diff --git a/protocols/rdp/guac_rdpsnd/messages.c b/protocols/rdp/guac_rdpsnd/messages.c index 4eed8e11..524e6595 100644 --- a/protocols/rdp/guac_rdpsnd/messages.c +++ b/protocols/rdp/guac_rdpsnd/messages.c @@ -18,6 +18,7 @@ * limitations under the License. */ +#include #include #include #include @@ -34,6 +35,7 @@ #include "audio.h" #include "service.h" #include "messages.h" +#include "client.h" /* MESSAGE HANDLERS */ @@ -53,6 +55,9 @@ void guac_rdpsnd_process_message_formats(guac_rdpsndPlugin* rdpsnd, uint8* data_mark; int pos; + rdp_guac_client_data* guac_client_data = + (rdp_guac_client_data*) audio->client->data; + stream_seek_uint32(input_stream); /* dwFlags */ stream_seek_uint32(input_stream); /* dwVolume */ stream_seek_uint32(input_stream); /* dwPitch */ @@ -147,6 +152,7 @@ void guac_rdpsnd_process_message_formats(guac_rdpsndPlugin* rdpsnd, stream_write_uint16(output_stream, n_out_formats); stream_set_pos(output_stream, pos); + pthread_mutex_lock(&(guac_client_data->rdp_lock)); svc_plugin_send((rdpSvcPlugin*)rdpsnd, output_stream); if (wVersion >= 6) { @@ -162,6 +168,8 @@ void guac_rdpsnd_process_message_formats(guac_rdpsndPlugin* rdpsnd, svc_plugin_send((rdpSvcPlugin*)rdpsnd, output_stream); } + pthread_mutex_unlock(&(guac_client_data->rdp_lock)); + } /* server is getting a feel of the round trip time */ @@ -172,6 +180,9 @@ void guac_rdpsnd_process_message_training(guac_rdpsndPlugin* rdpsnd, uint16 wPackSize; STREAM* output_stream; + rdp_guac_client_data* guac_client_data = + (rdp_guac_client_data*) audio->client->data; + /* Read timestamp */ stream_read_uint16(input_stream, wTimeStamp); stream_read_uint16(input_stream, wPackSize); @@ -184,7 +195,9 @@ void guac_rdpsnd_process_message_training(guac_rdpsndPlugin* rdpsnd, stream_write_uint16(output_stream, wTimeStamp); stream_write_uint16(output_stream, wPackSize); + pthread_mutex_lock(&(guac_client_data->rdp_lock)); svc_plugin_send((rdpSvcPlugin*) rdpsnd, output_stream); + pthread_mutex_unlock(&(guac_client_data->rdp_lock)); } @@ -221,6 +234,9 @@ void rdpsnd_process_message_wave(guac_rdpsndPlugin* rdpsnd, unsigned char* buffer = stream_get_head(input_stream); + rdp_guac_client_data* guac_client_data = + (rdp_guac_client_data*) audio->client->data; + rdpsnd->expectingWave = 0; memcpy(buffer, rdpsnd->waveData, 4); @@ -236,7 +252,10 @@ void rdpsnd_process_message_wave(guac_rdpsndPlugin* rdpsnd, stream_write_uint8(output_stream, rdpsnd->cBlockNo); /* cConfirmedBlockNo */ stream_write_uint8(output_stream, 0); /* bPad */ + pthread_mutex_lock(&(guac_client_data->rdp_lock)); svc_plugin_send(plugin, output_stream); + pthread_mutex_unlock(&(guac_client_data->rdp_lock)); + rdpsnd->plugin.interval_ms = 10; } diff --git a/protocols/rdp/include/client.h b/protocols/rdp/include/client.h index 9a1d55fc..0bc5b4e4 100644 --- a/protocols/rdp/include/client.h +++ b/protocols/rdp/include/client.h @@ -149,6 +149,11 @@ typedef struct rdp_guac_client_data { */ pthread_mutex_t update_lock; + /** + * Lock which is locked and unlocked for each RDP message. + */ + pthread_mutex_t rdp_lock; + pthread_mutexattr_t attributes; } rdp_guac_client_data; diff --git a/protocols/rdp/src/client.c b/protocols/rdp/src/client.c index fc218120..a1aba93a 100644 --- a/protocols/rdp/src/client.c +++ b/protocols/rdp/src/client.c @@ -460,13 +460,19 @@ int guac_client_init(guac_client* client, int argc, char** argv) { guac_client_data->clipboard = NULL; guac_client_data->audio = NULL; - /* Init update lock */ + /* Recursive attribute for locks */ pthread_mutexattr_init(&(guac_client_data->attributes)); pthread_mutexattr_settype(&(guac_client_data->attributes), PTHREAD_MUTEX_RECURSIVE); + + /* Init update lock */ pthread_mutex_init(&(guac_client_data->update_lock), &(guac_client_data->attributes)); + /* Init RDP lock */ + pthread_mutex_init(&(guac_client_data->rdp_lock), + &(guac_client_data->attributes)); + /* Clear keysym state mapping and keymap */ memset(guac_client_data->keysym_state, 0, sizeof(guac_rdp_keysym_state_map)); diff --git a/protocols/rdp/src/guac_handlers.c b/protocols/rdp/src/guac_handlers.c index 0f9efe37..e72ac343 100644 --- a/protocols/rdp/src/guac_handlers.c +++ b/protocols/rdp/src/guac_handlers.c @@ -218,6 +218,8 @@ int rdp_guac_client_mouse_handler(guac_client* client, int x, int y, int mask) { rdp_guac_client_data* guac_client_data = (rdp_guac_client_data*) client->data; freerdp* rdp_inst = guac_client_data->rdp_inst; + pthread_mutex_lock(&(guac_client_data->rdp_lock)); + /* If button mask unchanged, just send move event */ if (mask == guac_client_data->mouse_button_mask) rdp_inst->input->MouseEvent(rdp_inst->input, PTR_FLAGS_MOVE, x, y); @@ -283,6 +285,8 @@ int rdp_guac_client_mouse_handler(guac_client* client, int x, int y, int mask) { guac_client_data->mouse_button_mask = mask; } + pthread_mutex_unlock(&(guac_client_data->rdp_lock)); + return 0; } @@ -302,6 +306,8 @@ int __guac_rdp_send_keysym(guac_client* client, int keysym, int pressed) { /* If defined, send event */ if (keysym_desc->scancode != 0) { + pthread_mutex_lock(&(guac_client_data->rdp_lock)); + /* If defined, send any prerequesite keys that must be set */ if (keysym_desc->set_keysyms != NULL) __guac_rdp_update_keysyms(client, keysym_desc->set_keysyms, 0, 1); @@ -325,6 +331,8 @@ int __guac_rdp_send_keysym(guac_client* client, int keysym, int pressed) { if (keysym_desc->clear_keysyms != NULL) __guac_rdp_update_keysyms(client, keysym_desc->clear_keysyms, 1, 1); + pthread_mutex_unlock(&(guac_client_data->rdp_lock)); + return 0; } @@ -352,10 +360,15 @@ int __guac_rdp_send_keysym(guac_client* client, int keysym, int pressed) { guac_client_log_info(client, "Translated keysym 0x%x to U+%04X", keysym, codepoint); + pthread_mutex_lock(&(guac_client_data->rdp_lock)); + /* Send Unicode event */ rdp_inst->input->UnicodeKeyboardEvent( rdp_inst->input, 0, codepoint); + + pthread_mutex_unlock(&(guac_client_data->rdp_lock)); + } else