From 61c451abc8dc8d9a3b94becb9b64de589cab8cb0 Mon Sep 17 00:00:00 2001 From: James Muehlner Date: Wed, 15 Nov 2023 19:01:09 +0000 Subject: [PATCH] Maybe we can just use built in UUID functions for generating IDs? --- configure.ac | 83 ++++++++++++++++++---------------- src/libguac/client.c | 43 +++++++++++++++++- src/libguac/guacamole/client.h | 8 ++++ src/libguac/id.c | 51 +++++++++++++++------ 4 files changed, 129 insertions(+), 56 deletions(-) diff --git a/configure.ac b/configure.ac index 6d3a56398..5639da83e 100644 --- a/configure.ac +++ b/configure.ac @@ -94,49 +94,52 @@ AC_CHECK_LIB([dl], [dlopen], AC_MSG_ERROR("libdl is required on systems which do not otherwise provide dlopen()"), [#include ])]) -# -# libuuid -# - -have_libuuid=disabled -AC_ARG_WITH([libuuid], - [AS_HELP_STRING([--with-libuuid], - [use libuuid to generate unique identifiers @<:@default=check@:>@])], - [], - [with_libuuid=check]) - -if test "x$with_libuuid" != "xno" +if test "x$with_cygwin" = "xno" then - have_libuuid=yes - AC_CHECK_LIB([uuid], [uuid_generate], - [UUID_LIBS=-luuid] - [AC_DEFINE([HAVE_LIBUUID],, [Whether libuuid is available])], - [have_libuuid=no]) -fi + # + # libuuid + # + + have_libuuid=disabled + AC_ARG_WITH([libuuid], + [AS_HELP_STRING([--with-libuuid], + [use libuuid to generate unique identifiers @<:@default=check@:>@])], + [], + [with_libuuid=check]) -# OSSP UUID (if libuuid is unavilable) -if test "x${have_libuuid}" != "xyes" -then + if test "x$with_libuuid" != "xno" + then + have_libuuid=yes + AC_CHECK_LIB([uuid], [uuid_generate], + [UUID_LIBS=-luuid] + [AC_DEFINE([HAVE_LIBUUID],, [Whether libuuid is available])], + [have_libuuid=no]) + fi - AC_CHECK_LIB([ossp-uuid], [uuid_make], [UUID_LIBS=-lossp-uuid], - AC_CHECK_LIB([uuid], [uuid_make], [UUID_LIBS=-luuid], - AC_MSG_ERROR([ - -------------------------------------------- - Unable to find libuuid or the OSSP UUID library. - Either libuuid (from util-linux) or the OSSP UUID library is required for - guacamole-server to be built. - --------------------------------------------]))) - - # Check for and validate OSSP uuid.h header - AC_CHECK_HEADERS([ossp/uuid.h]) - AC_CHECK_DECL([uuid_make],, - AC_MSG_ERROR("No OSSP uuid.h found in include path"), - [#ifdef HAVE_OSSP_UUID_H - #include - #else - #include - #endif - ]) + # OSSP UUID (if libuuid is unavilable) + if test "x${have_libuuid}" != "xyes" + then + + AC_CHECK_LIB([ossp-uuid], [uuid_make], [UUID_LIBS=-lossp-uuid], + AC_CHECK_LIB([uuid], [uuid_make], [UUID_LIBS=-luuid], + AC_MSG_ERROR([ + -------------------------------------------- + Unable to find libuuid or the OSSP UUID library. + Either libuuid (from util-linux) or the OSSP UUID library is required for + guacamole-server to be built. + --------------------------------------------]))) + + # Check for and validate OSSP uuid.h header + AC_CHECK_HEADERS([ossp/uuid.h]) + AC_CHECK_DECL([uuid_make],, + AC_MSG_ERROR("No OSSP uuid.h found in include path"), + [#ifdef HAVE_OSSP_UUID_H + #include + #else + #include + #endif + ]) + fi fi # cunit diff --git a/src/libguac/client.c b/src/libguac/client.c index ddaca1045..6c3b3aedd 100644 --- a/src/libguac/client.c +++ b/src/libguac/client.c @@ -46,6 +46,10 @@ #include #include +#ifdef CYGWIN_BUILD +#include +#endif + /** * The number of nanoseconds between times that the pending users list will be * synchronized and emptied (250 milliseconds aka 1/4 second). @@ -161,10 +165,24 @@ void guac_client_free_stream(guac_client* client, guac_stream* stream) { * * @param data * The client for which all pending users should be promoted. + * + * @param timerOrWaitFired + * Unused - Windows only. */ -static void guac_client_promote_pending_users(union sigval data) { +static void guac_client_promote_pending_users( +#ifdef CYGWIN_BUILD + LPVOID data, + BOOLEAN timerOrWaitFired +#else + union sigval data +#endif + ) { +#ifdef CYGWIN_BUILD + guac_client* client = (guac_client*) data; +#else guac_client* client = (guac_client*) data.sival_ptr; +#endif pthread_mutex_lock(&(client->__pending_users_timer_mutex)); @@ -365,8 +383,13 @@ void guac_client_free(guac_client* client) { pthread_mutex_unlock(&(client->__pending_users_timer_mutex)); /* If the timer was registered, stop it before destroying the lock */ - if (was_started) + if (was_started) { +#ifdef CYGWIN_BUILD + DeleteTimerQueueTimer(NULL, client->__pending_users_timer, NULL); +#else timer_delete(client->__pending_users_timer); +#endif + } pthread_mutex_destroy(&(client->__pending_users_timer_mutex)); @@ -493,6 +516,21 @@ static int guac_client_start_pending_users_timer(guac_client* client) { return 0; } +#ifdef CYGWIN_BUILD + if (!CreateTimerQueueTimer( + &(client->__pending_users_timer)), + NULL, + guac_client_promote_pending_users, + client, + GUAC_CLIENT_PENDING_USERS_REFRESH_INTERVAL, + GUAC_CLIENT_PENDING_USERS_REFRESH_INTERVAL + 0) { + + // oh noes error + return 1; + } +#else + /* Configure the timer to synchronize and clear the pending users */ struct sigevent signal_config = { .sigev_notify = SIGEV_THREAD, @@ -507,6 +545,7 @@ static int guac_client_start_pending_users_timer(guac_client* client) { pthread_mutex_unlock(&(client->__pending_users_timer_mutex)); return 1; } +#endif /* Configure the pending users timer to run on the defined interval */ struct itimerspec time_config = { diff --git a/src/libguac/guacamole/client.h b/src/libguac/guacamole/client.h index 328965667..d904ce4cc 100644 --- a/src/libguac/guacamole/client.h +++ b/src/libguac/guacamole/client.h @@ -45,6 +45,10 @@ #include #include +#ifdef CYGWIN_BUILD +#include +#endif + struct guac_client { /** @@ -192,7 +196,11 @@ struct guac_client { * use within the client. This will be NULL until the first user joins * the connection, as it is lazily instantiated at that time. */ +#ifdef CYGWIN_BUILD + HANDLE __pending_users_timer; +#else timer_t __pending_users_timer; +#endif /** * A flag storing the current state of the pending users timer. diff --git a/src/libguac/id.c b/src/libguac/id.c index 610f836d5..c42bdff81 100644 --- a/src/libguac/id.c +++ b/src/libguac/id.c @@ -22,7 +22,10 @@ #include "guacamole/error.h" #include -#if defined(HAVE_LIBUUID) + +#ifdef CYGWIN_BUILD +#include +#elif defined(HAVE_LIBUUID) #include #elif defined(HAVE_OSSP_UUID_H) #include @@ -37,6 +40,38 @@ char* guac_generate_id(char prefix) { char* buffer; char* identifier; + /* Allocate buffer for future formatted ID */ + buffer = malloc(GUAC_UUID_LEN + 1); + if (buffer == NULL) { + guac_error = GUAC_STATUS_NO_MEMORY; + guac_error_message = "Could not allocate memory for unique ID"; + return NULL; + } + + identifier = &(buffer[1]); + +#ifdef CYGWIN_BUILD + + /* Generate a UUID using a built in windows function */ + UUID uuid; + UuidCreate(&uuid); + + /* Convert the UUID to an all-caps, null-terminated tring */ + RPC_CSTR uuid_string; + if (UuidToString(uuid, &uuid_string) == RPC_S_OUT_OF_MEMORY) { + guac_error = GUAC_STATUS_NO_MEMORY; + guac_error_message = "Could not allocate memory for unique ID"; + return NULL; + } + + /* Copy over lowercase letters to the final target string */ + for (int i = 0; i < GUAC_UUID_LEN; i++) + identifier[i] = tolower(uuid_string[i]); + + RpcStringFree(uuid_string); + +#else + /* Prepare object to receive generated UUID */ #ifdef HAVE_LIBUUID uuid_t uuid; @@ -61,19 +96,6 @@ char* guac_generate_id(char prefix) { } #endif - /* Allocate buffer for future formatted ID */ - buffer = malloc(GUAC_UUID_LEN + 1); - if (buffer == NULL) { -#ifndef HAVE_LIBUUID - uuid_destroy(uuid); -#endif - guac_error = GUAC_STATUS_NO_MEMORY; - guac_error_message = "Could not allocate memory for unique ID"; - return NULL; - } - - identifier = &(buffer[1]); - /* Convert UUID to string to produce unique identifier */ #ifdef HAVE_LIBUUID uuid_unparse_lower(uuid, identifier); @@ -89,6 +111,7 @@ char* guac_generate_id(char prefix) { /* Clean up generated UUID */ uuid_destroy(uuid); +#endif #endif buffer[0] = prefix;