Skip to content

Commit

Permalink
Maybe we can just use built in UUID functions for generating IDs?
Browse files Browse the repository at this point in the history
  • Loading branch information
jmuehlner committed Nov 15, 2023
1 parent 3a8a23e commit d3d41e2
Show file tree
Hide file tree
Showing 4 changed files with 129 additions and 56 deletions.
83 changes: 43 additions & 40 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -94,49 +94,52 @@ AC_CHECK_LIB([dl], [dlopen],
AC_MSG_ERROR("libdl is required on systems which do not otherwise provide dlopen()"),
[#include <dlfcn.h>])])

#
# 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 <ossp/uuid.h>
#else
#include <uuid.h>
#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 <ossp/uuid.h>
#else
#include <uuid.h>
#endif
])
fi
fi

# cunit
Expand Down
43 changes: 41 additions & 2 deletions src/libguac/client.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@
#include <stdlib.h>
#include <string.h>

#ifdef CYGWIN_BUILD
#include <synchapi.h>
#endif

/**
* The number of nanoseconds between times that the pending users list will be
* synchronized and emptied (250 milliseconds aka 1/4 second).
Expand Down Expand Up @@ -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));

Expand Down Expand Up @@ -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));

Expand Down Expand Up @@ -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,
Expand All @@ -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 = {
Expand Down
8 changes: 8 additions & 0 deletions src/libguac/guacamole/client.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@
#include <stdarg.h>
#include <time.h>

#ifdef CYGWIN_BUILD
#include <WinNT.h>
#endif

struct guac_client {

/**
Expand Down Expand Up @@ -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.
Expand Down
51 changes: 37 additions & 14 deletions src/libguac/id.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,10 @@
#include "guacamole/error.h"
#include <guacamole/id.h>

#if defined(HAVE_LIBUUID)

#ifdef CYGWIN_BUILD
#include <rpcdce.h>
#elif defined(HAVE_LIBUUID)
#include <uuid/uuid.h>
#elif defined(HAVE_OSSP_UUID_H)
#include <ossp/uuid.h>
Expand All @@ -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;
Expand All @@ -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);
Expand All @@ -89,6 +111,7 @@ char* guac_generate_id(char prefix) {

/* Clean up generated UUID */
uuid_destroy(uuid);
#endif
#endif

buffer[0] = prefix;
Expand Down

0 comments on commit d3d41e2

Please sign in to comment.