diff --git a/src/common/display.c b/src/common/display.c index 73177bf748..c9d6720812 100644 --- a/src/common/display.c +++ b/src/common/display.c @@ -28,6 +28,8 @@ #include #include +#include + /** * Synchronizes all surfaces within the given linked list to the given socket. * If the provided pointer to the linked list is NULL, this function has no @@ -167,23 +169,39 @@ void guac_common_display_dup( guac_common_display* display, guac_client* client, guac_socket* socket) { + fprintf(stderr, "guac_common_display_dup start\n"); + pthread_mutex_lock(&display->_lock); + fprintf(stderr, "pthread_mutex_lock(&display->_lock); done\n"); + /* Sunchronize shared cursor */ guac_common_cursor_dup(display->cursor, client, socket); + fprintf(stderr, "guac_common_cursor_dup(display->cursor, client, socket); done\n"); + /* Synchronize default surface */ guac_common_surface_dup(display->default_surface, client, socket); + fprintf(stderr, "guac_common_surface_dup(display->default_surface, client, socket); done\n"); + /* Synchronize all layers and buffers */ guac_common_display_dup_layers(display->layers, client, socket); + + fprintf(stderr, "guac_common_display_dup_layers(display->layers, client, socket); done\n"); guac_common_display_dup_layers(display->buffers, client, socket); + fprintf(stderr, "guac_common_display_dup_layers(display->buffers, client, socket); done\n"); + /* Sends a sync instruction to mark the boundary of the first frame */ guac_protocol_send_sync(socket, client->last_sent_timestamp, 1); + fprintf(stderr, "guac_protocol_send_sync(socket, client->last_sent_timestamp, 1); done\n"); + pthread_mutex_unlock(&display->_lock); + fprintf(stderr, "guac_common_display_dup end\n"); + } void guac_common_display_set_lossless(guac_common_display* display, diff --git a/src/libguac/client.c b/src/libguac/client.c index b904fb7e42..788a8169ef 100644 --- a/src/libguac/client.c +++ b/src/libguac/client.c @@ -252,6 +252,8 @@ static void guac_client_promote_pending_users(union sigval data) { guac_client* guac_client_alloc() { + fprintf(stderr, "guac_client_alloc start\n"); + int i; /* Allocate new client */ @@ -308,12 +310,16 @@ guac_client* guac_client_alloc() { client->socket = guac_socket_broadcast(client); client->pending_socket = guac_socket_broadcast_pending(client); + fprintf(stderr, "guac_client_alloc end\n"); + return client; } void guac_client_free(guac_client* client) { + fprintf(stderr, "guac_client_free start\n"); + /* Acquire write locks before referencing user pointers */ guac_rwlock_acquire_write_lock(&(client->__pending_users_lock)); guac_rwlock_acquire_write_lock(&(client->__users_lock)); @@ -376,6 +382,8 @@ void guac_client_free(guac_client* client) { free(client->connection_id); free(client); + + fprintf(stderr, "guac_client_free end\n"); } void vguac_client_log(guac_client* client, guac_client_log_level level, @@ -450,6 +458,8 @@ void guac_client_abort(guac_client* client, guac_protocol_status status, static void guac_client_add_pending_user( guac_client* client, guac_user* user) { + fprintf(stderr, "guac_client_add_pending_user start\n"); + /* Acquire the lock for modifying the list of pending users */ guac_rwlock_acquire_write_lock(&(client->__pending_users_lock)); @@ -467,6 +477,8 @@ static void guac_client_add_pending_user( /* Release the lock */ guac_rwlock_release_lock(&(client->__pending_users_lock)); + fprintf(stderr, "guac_client_add_pending_user end\n"); + } /** @@ -484,6 +496,8 @@ static void guac_client_add_pending_user( */ static int guac_client_start_pending_users_timer(guac_client* client) { + fprintf(stderr, "guac_client_start_pending_users_timer start\n"); + pthread_mutex_lock(&(client->__pending_users_timer_mutex)); /* Return success if the timer is already created and running */ @@ -526,12 +540,17 @@ static int guac_client_start_pending_users_timer(guac_client* client) { client->__pending_users_timer_state = GUAC_CLIENT_PENDING_TIMER_REGISTERED; pthread_mutex_unlock(&(client->__pending_users_timer_mutex)); + + fprintf(stderr, "guac_client_start_pending_users_timer end\n"); + return 0; } int guac_client_add_user(guac_client* client, guac_user* user, int argc, char** argv) { + fprintf(stderr, "guac_client_add_user start\n"); + /* Create and start the timer if it hasn't already been initialized */ if (guac_client_start_pending_users_timer(client)) { @@ -569,12 +588,16 @@ int guac_client_add_user(guac_client* client, guac_user* user, int argc, char** if (retval == 0 && !user->owner) guac_client_owner_notify_join(client, user); + fprintf(stderr, "guac_client_add_user end\n"); + return retval; } void guac_client_remove_user(guac_client* client, guac_user* user) { + fprintf(stderr, "guac_client_remove_user start\n"); + guac_rwlock_acquire_write_lock(&(client->__pending_users_lock)); guac_rwlock_acquire_write_lock(&(client->__users_lock)); @@ -609,10 +632,14 @@ void guac_client_remove_user(guac_client* client, guac_user* user) { else if (client->leave_handler) client->leave_handler(user); + fprintf(stderr, "guac_client_remove_user end\n"); + } void guac_client_foreach_user(guac_client* client, guac_user_callback* callback, void* data) { + fprintf(stderr, "guac_client_foreach_user start\n"); + guac_user* current; guac_rwlock_acquire_read_lock(&(client->__users_lock)); @@ -626,11 +653,15 @@ void guac_client_foreach_user(guac_client* client, guac_user_callback* callback, guac_rwlock_release_lock(&(client->__users_lock)); + fprintf(stderr, "guac_client_foreach_user end\n"); + } void guac_client_foreach_pending_user( guac_client* client, guac_user_callback* callback, void* data) { + fprintf(stderr, "guac_client_foreach_pending_user start\n"); + guac_user* current; guac_rwlock_acquire_read_lock(&(client->__pending_users_lock)); @@ -644,11 +675,15 @@ void guac_client_foreach_pending_user( guac_rwlock_release_lock(&(client->__pending_users_lock)); + fprintf(stderr, "guac_client_foreach_pending_user end\n"); + } void* guac_client_for_owner(guac_client* client, guac_user_callback* callback, void* data) { + fprintf(stderr, "guac_client_for_owner start\n"); + void* retval; guac_rwlock_acquire_read_lock(&(client->__users_lock)); @@ -658,6 +693,8 @@ void* guac_client_for_owner(guac_client* client, guac_user_callback* callback, guac_rwlock_release_lock(&(client->__users_lock)); + fprintf(stderr, "guac_client_for_owner end\n"); + /* Return value from callback */ return retval; @@ -666,6 +703,8 @@ void* guac_client_for_owner(guac_client* client, guac_user_callback* callback, void* guac_client_for_user(guac_client* client, guac_user* user, guac_user_callback* callback, void* data) { + fprintf(stderr, "guac_client_for_user start\n"); + guac_user* current; int user_valid = 0; @@ -695,6 +734,8 @@ void* guac_client_for_user(guac_client* client, guac_user* user, guac_rwlock_release_lock(&(client->__users_lock)); + fprintf(stderr, "guac_client_for_user end\n"); + /* Return value from callback */ return retval; @@ -706,6 +747,8 @@ int guac_client_end_frame(guac_client* client) { int guac_client_end_multiple_frames(guac_client* client, int frames) { + fprintf(stderr, "guac_client_end_multiple_frames start\n"); + /* Update and send timestamp */ client->last_sent_timestamp = guac_timestamp_current(); @@ -713,12 +756,16 @@ int guac_client_end_multiple_frames(guac_client* client, int frames) { guac_client_log(client, GUAC_LOG_TRACE, "Server completed " "frame %" PRIu64 "ms (%i logical frames)", client->last_sent_timestamp, frames); + fprintf(stderr, "guac_client_end_multiple_frames end\n"); + return guac_protocol_send_sync(client->socket, client->last_sent_timestamp, frames); } int guac_client_load_plugin(guac_client* client, const char* protocol) { + fprintf(stderr, "guac_client_load_plugin start\n"); + /* Reference to dlopen()'d plugin */ void* client_plugin_handle; @@ -766,6 +813,8 @@ int guac_client_load_plugin(guac_client* client, const char* protocol) { /* Init client */ client->__plugin_handle = client_plugin_handle; + fprintf(stderr, "guac_client_load_plugin end\n"); + return alias.client_init(client); } @@ -1043,6 +1092,8 @@ int guac_client_owner_supports_required(guac_client* client) { */ static void* guac_client_owner_notify_join_callback(guac_user* user, void* data) { + fprintf(stderr, "guac_client_owner_notify_join_callback start\n"); + const guac_user* joiner = (const guac_user *) data; if (user == NULL) @@ -1064,6 +1115,8 @@ static void* guac_client_owner_notify_join_callback(guac_user* user, void* data) /* Send user joined notification to owner. */ const char* args[] = { (const char*)joiner->user_id, (const char*)send_joiner, NULL }; + + fprintf(stderr, "guac_client_owner_notify_join_callback end\n"); return (void*) ((intptr_t) guac_protocol_send_msg(user->socket, GUAC_MESSAGE_USER_JOINED, args)); } @@ -1102,6 +1155,8 @@ int guac_client_owner_notify_join(guac_client* client, guac_user* joiner) { */ static void* guac_client_owner_notify_leave_callback(guac_user* user, void* data) { + fprintf(stderr, "guac_client_owner_notify_leave_callback start\n"); + const guac_user* quitter = (const guac_user *) data; if (user == NULL) diff --git a/src/protocols/vnc/client.c b/src/protocols/vnc/client.c index ea7d44b3cb..341c7ad44f 100644 --- a/src/protocols/vnc/client.c +++ b/src/protocols/vnc/client.c @@ -55,10 +55,14 @@ */ static void* guac_vnc_sync_pending_user_audio(guac_user* user, void* data) { + fprintf(stderr, "guac_vnc_sync_pending_user_audio start\n"); + /* Add the user to the stream */ guac_pa_stream* audio = (guac_pa_stream*) data; guac_pa_stream_add_user(audio, user); + fprintf(stderr, "guac_vnc_sync_pending_user_audio end\n"); + return NULL; } @@ -76,10 +80,14 @@ static void* guac_vnc_sync_pending_user_audio(guac_user* user, void* data) { */ static int guac_vnc_join_pending_handler(guac_client* client) { + fprintf(stderr, "guac_vnc_join_pending_handler start\n"); + guac_vnc_client* vnc_client = (guac_vnc_client*) client->data; guac_socket* broadcast_socket = client->pending_socket; #ifdef ENABLE_PULSE + + fprintf(stderr, "calling guac_vnc_sync_pending_user_audio()\n"); /* Synchronize any audio stream for each pending user */ if (vnc_client->audio) guac_client_foreach_pending_user( @@ -92,12 +100,16 @@ static int guac_vnc_join_pending_handler(guac_client* client) { guac_socket_flush(broadcast_socket); } + fprintf(stderr, "guac_vnc_join_pending_handler end\n"); + return 0; } int guac_client_init(guac_client* client) { + fprintf(stderr, "guac_client_init (VNC) start\n"); + /* Set client args */ client->args = GUAC_VNC_CLIENT_ARGS; @@ -119,11 +131,15 @@ int guac_client_init(guac_client* client) { client->leave_handler = guac_vnc_user_leave_handler; client->free_handler = guac_vnc_client_free_handler; + fprintf(stderr, "guac_client_init (VNC) end\n"); + return 0; } int guac_vnc_client_free_handler(guac_client* client) { + fprintf(stderr, "guac_vnc_client_free_handler start\n"); + guac_vnc_client* vnc_client = (guac_vnc_client*) client->data; guac_vnc_settings* settings = vnc_client->settings; @@ -211,6 +227,8 @@ int guac_vnc_client_free_handler(guac_client* client) { /* Free generic data struct */ free(client->data); + fprintf(stderr, "guac_vnc_client_free_handler (VNC) end\n"); + return 0; } diff --git a/src/protocols/vnc/vnc.c b/src/protocols/vnc/vnc.c index 3b94d5e759..fd72c2c68d 100644 --- a/src/protocols/vnc/vnc.c +++ b/src/protocols/vnc/vnc.c @@ -128,13 +128,20 @@ static rfbBool guac_vnc_unlock_write_to_tls(rfbClient* rfb_client) { rfbClient* guac_vnc_get_client(guac_client* client) { + fprintf(stderr, "guac_vnc_get_client start\n"); + rfbClient* rfb_client = rfbGetClient(8, 3, 4); /* 32-bpp client */ guac_vnc_client* vnc_client = (guac_vnc_client*) client->data; guac_vnc_settings* vnc_settings = vnc_client->settings; + fprintf(stderr, "guac_vnc_get_client did rfbGetClient\n"); + /* Store Guac client in rfb client */ rfbClientSetClientData(rfb_client, GUAC_VNC_CLIENT_KEY, client); + fprintf(stderr, "guac_vnc_get_client did rfbClientSetClientData\n"); + + /* Framebuffer update handler */ rfb_client->GotFrameBufferUpdate = guac_vnc_update; rfb_client->GotCopyRect = guac_vnc_copyrect; @@ -146,6 +153,8 @@ rfbClient* guac_vnc_get_client(guac_client* client) { #endif #ifdef LIBVNCSERVER_WITH_CLIENT_GCRYPT + + fprintf(stderr, "guac_vnc_get_client LIBVNCSERVER_WITH_CLIENT_GCRYPT\n"); /* Check if GCrypt is initialized, do it if not. */ if (!gcry_control(GCRYCTL_INITIALIZATION_FINISHED_P)) { @@ -196,6 +205,8 @@ rfbClient* guac_vnc_get_client(guac_client* client) { /* Depth */ guac_vnc_set_pixel_format(rfb_client, vnc_settings->color_depth); + fprintf(stderr, "guac_vnc_get_client did guac_vnc_set_pixel_format\n"); + /* Hook into allocation so we can handle resize. */ vnc_client->rfb_MallocFrameBuffer = rfb_client->MallocFrameBuffer; rfb_client->MallocFrameBuffer = guac_vnc_malloc_framebuffer; @@ -231,9 +242,17 @@ rfbClient* guac_vnc_get_client(guac_client* client) { if (vnc_settings->encodings) rfb_client->appData.encodingsString = strdup(vnc_settings->encodings); + fprintf(stderr, "guac_vnc_get_client about to rfbInitClient\n"); + /* Connect */ - if (rfbInitClient(rfb_client, NULL, NULL)) + if (rfbInitClient(rfb_client, NULL, NULL)) { + + + fprintf(stderr, "guac_vnc_get_client did rfbInitClient\n"); return rfb_client; + } + + fprintf(stderr, "guac_vnc_get_client failed rfbInitClient\n"); /* If connection fails, return NULL */ return NULL; @@ -268,6 +287,8 @@ static int guac_vnc_wait_for_messages(rfbClient* rfb_client, int timeout) { void* guac_vnc_client_thread(void* data) { + fprintf(stderr, "guac_vnc_client_thread start\n"); + guac_client* client = (guac_client*) data; guac_vnc_client* vnc_client = (guac_vnc_client*) client->data; guac_vnc_settings* settings = vnc_client->settings; @@ -286,6 +307,8 @@ void* guac_vnc_client_thread(void* data) { if (settings->wol_wait_time > 0) guac_timestamp_msleep(settings->wol_wait_time * 1000); } + + fprintf(stderr, "guac_vnc_client_thread done with wol stuff\n"); /* Configure clipboard encoding */ if (guac_vnc_set_clipboard_encoding(client, settings->clipboard_encoding)) { @@ -293,6 +316,8 @@ void* guac_vnc_client_thread(void* data) { "clipboard encoding: '%s'.", settings->clipboard_encoding); } + fprintf(stderr, "guac_vnc_client_thread done with guac_vnc_set_clipboard_encoding\n"); + /* Set up libvncclient logging */ rfbClientLog = guac_vnc_client_log_info; rfbClientErr = guac_vnc_client_log_error; @@ -301,6 +326,8 @@ void* guac_vnc_client_thread(void* data) { rfbClient* rfb_client = guac_vnc_get_client(client); int retries_remaining = settings->retries; + fprintf(stderr, "guac_vnc_client_thread done with guac_vnc_get_client\n"); + /* If unsuccessful, retry as many times as specified */ while (!rfb_client && retries_remaining > 0) { @@ -322,6 +349,8 @@ void* guac_vnc_client_thread(void* data) { return NULL; } + fprintf(stderr, "guac_vnc_client_thread deffo connected\n"); + #ifdef ENABLE_PULSE /* If audio is enabled, start streaming via PulseAudio */ if (settings->audio_enabled) @@ -332,9 +361,13 @@ void* guac_vnc_client_thread(void* data) { #ifdef ENABLE_COMMON_SSH guac_common_ssh_init(client); + fprintf(stderr, "guac_vnc_client_thread done with guac_common_ssh_init\n"); + /* Connect via SSH if SFTP is enabled */ if (settings->enable_sftp) { + fprintf(stderr, "guac_vnc_client_thread doing sftp stuff\n"); + /* Abort if username is missing */ if (settings->sftp_username == NULL) { guac_client_abort(client, GUAC_PROTOCOL_STATUS_SERVER_ERROR, @@ -416,6 +449,10 @@ void* guac_vnc_client_thread(void* data) { } #endif + + + fprintf(stderr, "guac_vnc_client_thread done with sftp stuff\n"); + /* Set remaining client data */ vnc_client->rfb_client = rfb_client; @@ -431,14 +468,20 @@ void* guac_vnc_client_thread(void* data) { settings->recording_include_keys); } + fprintf(stderr, "guac_vnc_client_thread done with guac_recording_create\n"); + /* Create display */ vnc_client->display = guac_common_display_alloc(client, rfb_client->width, rfb_client->height); + fprintf(stderr, "guac_vnc_client_thread done with guac_common_display_alloc\n"); + /* Use lossless compression only if requested (otherwise, use default * heuristics) */ guac_common_display_set_lossless(vnc_client->display, settings->lossless); + fprintf(stderr, "guac_vnc_client_thread done with guac_common_display_set_lossless\n"); + /* If not read-only, set an appropriate cursor */ if (settings->read_only == 0) { if (settings->remote_cursor) @@ -448,16 +491,25 @@ void* guac_vnc_client_thread(void* data) { } + fprintf(stderr, "guac_vnc_client_thread done with cursor stuff\n"); + guac_socket_flush(client->socket); + fprintf(stderr, "guac_vnc_client_thread done with guac_socket_flush(client->socket);\n"); + guac_timestamp last_frame_end = guac_timestamp_current(); + fprintf(stderr, "guac_vnc_client_thread done current timestamp: %li\n", last_frame_end); + /* Handle messages from VNC server while client is running */ while (client->state == GUAC_CLIENT_RUNNING) { /* Wait for start of frame */ int wait_result = guac_vnc_wait_for_messages(rfb_client, GUAC_VNC_FRAME_START_TIMEOUT); + + fprintf(stderr, "got wait result: %i\n", wait_result); + if (wait_result > 0) { int processing_lag = guac_client_get_processing_lag(client); @@ -512,16 +564,22 @@ void* guac_vnc_client_thread(void* data) { if (wait_result < 0) guac_client_abort(client, GUAC_PROTOCOL_STATUS_UPSTREAM_ERROR, "Connection closed."); + fprintf(stderr, "guac_vnc_client_thread about to flush frame\n"); + /* Flush frame */ guac_common_surface_flush(vnc_client->display->default_surface); guac_client_end_frame(client); guac_socket_flush(client->socket); + fprintf(stderr, "guac_vnc_client_thread about flushed frame\n"); + } /* Kill client and finish connection */ guac_client_stop(client); guac_client_log(client, GUAC_LOG_INFO, "Internal VNC client disconnected"); + + fprintf(stderr, "guac_vnc_client_thread end\n"); return NULL; }