From 7ce7502e1ae23766ba40105327de787c2d1cef9d Mon Sep 17 00:00:00 2001 From: Havoc Pennington Date: Fri, 25 Feb 2005 22:03:30 +0000 Subject: 2005-02-25 Havoc Pennington * doc/dbus-specification.xml: document the GUID thing * dbus/dbus-server.c (_dbus_server_init_base): initialize a globally unique ID for the server, and put a "guid=hexencoded" field in the address * dbus/dbus-bus.c: fix missing #include of dbus-threads-internal.h * dbus/dbus-message.c: ditto * dbus/dbus-dataslot.c: ditto * dbus/dbus-list.c: ditto * dbus/dbus-internals.h: wait, just include dbus-threads-internal.h here * dbus/dbus-string.c (_dbus_string_copy_to_buffer): move back for use in main library * dbus/dbus-sysdeps.c (_dbus_generate_random_bytes_buffer): new function --- ChangeLog | 24 ++++++++++++++++ dbus/dbus-bus.c | 1 + dbus/dbus-dataslot.c | 2 +- dbus/dbus-internals.h | 2 +- dbus/dbus-list.c | 2 +- dbus/dbus-message.c | 1 + dbus/dbus-server-protected.h | 13 +++++++++ dbus/dbus-server.c | 68 ++++++++++++++++++++++++++++++++++++++++---- dbus/dbus-string-util.c | 24 ---------------- dbus/dbus-string.c | 24 ++++++++++++++++ dbus/dbus-sysdeps.c | 59 ++++++++++++++++++++++++++++++-------- dbus/dbus-sysdeps.h | 10 ++++--- doc/dbus-specification.xml | 22 ++++++++++++++ 13 files changed, 204 insertions(+), 48 deletions(-) diff --git a/ChangeLog b/ChangeLog index 759355e7..0f8daf25 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,27 @@ +2005-02-25 Havoc Pennington + + * doc/dbus-specification.xml: document the GUID thing + + * dbus/dbus-server.c (_dbus_server_init_base): initialize a + globally unique ID for the server, and put a "guid=hexencoded" + field in the address + + * dbus/dbus-bus.c: fix missing #include of dbus-threads-internal.h + + * dbus/dbus-message.c: ditto + + * dbus/dbus-dataslot.c: ditto + + * dbus/dbus-list.c: ditto + + * dbus/dbus-internals.h: wait, just include + dbus-threads-internal.h here + + * dbus/dbus-string.c (_dbus_string_copy_to_buffer): move back for + use in main library + + * dbus/dbus-sysdeps.c (_dbus_generate_random_bytes_buffer): new function + 2005-02-24 Colin Walters * test/glib/Makefile.am (EXTRA_DIST): Add test-service-glib.xml diff --git a/dbus/dbus-bus.c b/dbus/dbus-bus.c index 188418c2..fedee0f0 100644 --- a/dbus/dbus-bus.c +++ b/dbus/dbus-bus.c @@ -27,6 +27,7 @@ #include "dbus-internals.h" #include "dbus-message.h" #include "dbus-marshal-validate.h" +#include "dbus-threads-internal.h" #include /** diff --git a/dbus/dbus-dataslot.c b/dbus/dbus-dataslot.c index 8026d048..8a2937de 100644 --- a/dbus/dbus-dataslot.c +++ b/dbus/dbus-dataslot.c @@ -21,7 +21,7 @@ * */ #include "dbus-dataslot.h" -#include "dbus-threads.h" +#include "dbus-threads-internal.h" /** * @defgroup DBusDataSlot Data slots diff --git a/dbus/dbus-internals.h b/dbus/dbus-internals.h index dcbc6183..b141c23d 100644 --- a/dbus/dbus-internals.h +++ b/dbus/dbus-internals.h @@ -33,7 +33,7 @@ #include #include #include -#include +#include DBUS_BEGIN_DECLS diff --git a/dbus/dbus-list.c b/dbus/dbus-list.c index 949e70a8..7389c268 100644 --- a/dbus/dbus-list.c +++ b/dbus/dbus-list.c @@ -24,7 +24,7 @@ #include "dbus-internals.h" #include "dbus-list.h" #include "dbus-mempool.h" -#include "dbus-threads.h" +#include "dbus-threads-internal.h" /** * @defgroup DBusList Linked list diff --git a/dbus/dbus-message.c b/dbus/dbus-message.c index 7ff5762c..672a72b4 100644 --- a/dbus/dbus-message.c +++ b/dbus/dbus-message.c @@ -32,6 +32,7 @@ #include "dbus-object-tree.h" #include "dbus-memory.h" #include "dbus-list.h" +#include "dbus-threads-internal.h" #include /** diff --git a/dbus/dbus-server-protected.h b/dbus/dbus-server-protected.h index 284d02c5..dbbc3c62 100644 --- a/dbus/dbus-server-protected.h +++ b/dbus/dbus-server-protected.h @@ -35,6 +35,16 @@ DBUS_BEGIN_DECLS typedef struct DBusServerVTable DBusServerVTable; +typedef union DBusGUID DBusGUID; + +/** + * A server's globally unique ID + */ +union DBusGUID +{ + dbus_uint32_t as_uint32s[4]; + unsigned char as_bytes[16]; +}; /** * Virtual table to be implemented by all server "subclasses" @@ -56,6 +66,9 @@ struct DBusServer DBusAtomic refcount; /**< Reference count. */ const DBusServerVTable *vtable; /**< Virtual methods for this instance. */ DBusMutex *mutex; /**< Lock on the server object */ + + DBusGUID guid; /**< Globally unique ID of server */ + DBusWatchList *watches; /**< Our watches */ DBusTimeoutList *timeouts; /**< Our timeouts */ diff --git a/dbus/dbus-server.c b/dbus/dbus-server.c index 156d5ccd..20fb5f3c 100644 --- a/dbus/dbus-server.c +++ b/dbus/dbus-server.c @@ -52,6 +52,58 @@ * @{ */ +static void +init_guid (DBusGUID *guid) +{ + long now; + char *p; + int ts_size; + + _dbus_get_current_time (&now, NULL); + + guid->as_uint32s[0] = now; + + ts_size = sizeof (guid->as_uint32s[0]); + p = ((char*)guid->as_bytes) + ts_size; + + _dbus_generate_random_bytes_buffer (p, + sizeof (guid->as_bytes) - ts_size); +} + +/* this is a little fragile since it assumes the address doesn't + * already have a guid, but it shouldn't + */ +static char* +copy_address_with_guid_appended (const DBusString *address, + const DBusGUID *guid) +{ + DBusString with_guid; + DBusString guid_str; + char *retval; + + if (!_dbus_string_init (&with_guid)) + return NULL; + + _dbus_string_init_const_len (&guid_str, guid->as_bytes, + sizeof (guid->as_bytes)); + + if (!_dbus_string_copy (address, 0, &with_guid, 0) || + !_dbus_string_append (&with_guid, ",guid=") || + !_dbus_string_hex_encode (&guid_str, 0, + &with_guid, _dbus_string_get_length (&with_guid))) + { + _dbus_string_free (&with_guid); + return NULL; + } + + retval = NULL; + _dbus_string_copy_data (&with_guid, &retval); + + _dbus_string_free (&with_guid); + + return retval; /* may be NULL if copy failed */ +} + /** * Initializes the members of the DBusServer base class. * Chained up to by subclass constructors. @@ -65,17 +117,21 @@ dbus_bool_t _dbus_server_init_base (DBusServer *server, const DBusServerVTable *vtable, const DBusString *address) -{ +{ server->vtable = vtable; server->refcount.value = 1; server->address = NULL; server->watches = NULL; server->timeouts = NULL; - - if (!_dbus_string_copy_data (address, &server->address)) - goto failed; + init_guid (&server->guid); + + server->address = copy_address_with_guid_appended (address, + &server->guid); + if (server->address == NULL) + goto failed; + server->mutex = _dbus_mutex_new (); if (server->mutex == NULL) goto failed; @@ -438,7 +494,9 @@ dbus_server_listen (const char *address, for (i = 0; i < len; i++) { - const char *method = dbus_address_entry_get_method (entries[i]); + const char *method; + + method = dbus_address_entry_get_method (entries[i]); if (strcmp (method, "unix") == 0) { diff --git a/dbus/dbus-string-util.c b/dbus/dbus-string-util.c index 0610c66d..ddb9d750 100644 --- a/dbus/dbus-string-util.c +++ b/dbus/dbus-string-util.c @@ -31,30 +31,6 @@ * @{ */ -/** - * Copies the contents of a DBusString into a different - * buffer. The resulting buffer will be nul-terminated. - * - * @param str a string - * @param buffer a C buffer to copy data to - * @param avail_len maximum length of C buffer - */ -void -_dbus_string_copy_to_buffer (const DBusString *str, - char *buffer, - int avail_len) -{ - int copy_len; - DBUS_CONST_STRING_PREAMBLE (str); - - _dbus_assert (avail_len >= 0); - - copy_len = MIN (avail_len, real->len+1); - memcpy (buffer, real->str, copy_len); - if (avail_len > 0 && avail_len == copy_len) - buffer[avail_len-1] = '\0'; -} - /** * Returns whether a string ends with the given suffix * diff --git a/dbus/dbus-string.c b/dbus/dbus-string.c index 5088bca9..86d3eb83 100644 --- a/dbus/dbus-string.c +++ b/dbus/dbus-string.c @@ -708,6 +708,30 @@ _dbus_string_copy_data (const DBusString *str, return TRUE; } +/** + * Copies the contents of a DBusString into a different + * buffer. The resulting buffer will be nul-terminated. + * + * @param str a string + * @param buffer a C buffer to copy data to + * @param avail_len maximum length of C buffer + */ +void +_dbus_string_copy_to_buffer (const DBusString *str, + char *buffer, + int avail_len) +{ + int copy_len; + DBUS_CONST_STRING_PREAMBLE (str); + + _dbus_assert (avail_len >= 0); + + copy_len = MIN (avail_len, real->len+1); + memcpy (buffer, real->str, copy_len); + if (avail_len > 0 && avail_len == copy_len) + buffer[avail_len-1] = '\0'; +} + #ifdef DBUS_BUILD_TESTS /** * Copies a segment of the string into a char* diff --git a/dbus/dbus-sysdeps.c b/dbus/dbus-sysdeps.c index 83c1ce4c..830e26f1 100644 --- a/dbus/dbus-sysdeps.c +++ b/dbus/dbus-sysdeps.c @@ -2328,15 +2328,12 @@ _dbus_concat_dir_and_file (DBusString *dir, } static dbus_bool_t -pseudorandom_generate_random_bytes (DBusString *str, - int n_bytes) +pseudorandom_generate_random_bytes_buffer (char *buffer, + int n_bytes) { - int old_len; unsigned long tv_usec; int i; - old_len = _dbus_string_get_length (str); - /* fall back to pseudorandom */ _dbus_verbose ("Falling back to pseudorandom for %d bytes\n", n_bytes); @@ -2352,18 +2349,56 @@ pseudorandom_generate_random_bytes (DBusString *str, r = rand (); b = (r / (double) RAND_MAX) * 255.0; - - if (!_dbus_string_append_byte (str, b)) - goto failed; - + + buffer[i] = b; + ++i; } +} + +static dbus_bool_t +pseudorandom_generate_random_bytes (DBusString *str, + int n_bytes) +{ + int old_len; + char *p; + + old_len = _dbus_string_get_length (str); + + if (!_dbus_string_lengthen (str, n_bytes)) + return FALSE; + + p = _dbus_string_get_data_len (str, old_len, n_bytes); + + pseudorandom_generate_random_bytes_buffer (p, n_bytes); return TRUE; +} - failed: - _dbus_string_set_length (str, old_len); - return FALSE; +/** + * Fills n_bytes of the given buffer with random bytes. + * + * @param buffer an allocated buffer + * @param n_bytes the number of bytes in buffer to write to + */ +void +_dbus_generate_random_bytes_buffer (char *buffer, + int n_bytes) +{ + DBusString str; + + if (!_dbus_string_init (&str)) + return pseudorandom_generate_random_bytes_buffer (buffer, n_bytes); + + if (!_dbus_generate_random_bytes (&str, n_bytes)) + { + _dbus_string_free (&str); + return pseudorandom_generate_random_bytes_buffer (buffer, n_bytes); + } + + _dbus_string_copy_to_buffer (&str, buffer, n_bytes); + + _dbus_string_free (&str); } /** diff --git a/dbus/dbus-sysdeps.h b/dbus/dbus-sysdeps.h index dabf334c..6727630a 100644 --- a/dbus/dbus-sysdeps.h +++ b/dbus/dbus-sysdeps.h @@ -256,10 +256,12 @@ dbus_bool_t _dbus_directory_get_next_file (DBusDirIter *iter, void _dbus_directory_close (DBusDirIter *iter); -dbus_bool_t _dbus_generate_random_bytes (DBusString *str, - int n_bytes); -dbus_bool_t _dbus_generate_random_ascii (DBusString *str, - int n_bytes); +void _dbus_generate_random_bytes_buffer (char *buffer, + int n_bytes); +dbus_bool_t _dbus_generate_random_bytes (DBusString *str, + int n_bytes); +dbus_bool_t _dbus_generate_random_ascii (DBusString *str, + int n_bytes); const char *_dbus_errno_to_string (int errnum); const char* _dbus_error_from_errno (int error_number); diff --git a/doc/dbus-specification.xml b/doc/dbus-specification.xml index 1d47733c..ff625447 100644 --- a/doc/dbus-specification.xml +++ b/doc/dbus-specification.xml @@ -2165,6 +2165,28 @@ The set of optionally-escaped bytes is intended to preserve address readability and convenience. + + + A server may specify a key-value pair with the key guid + and the value a hex-encoded 16-byte sequence. This globally unique ID must + be created by filling the first 4 bytes with a 32-bit UNIX time since the + epoch, and the remaining 12 bytes with random bytes. If present, the GUID + may be used to distinguish one server from another. A server should use a + different GUID for each address it listens on. For example, if a message + bus daemon offers both UNIX domain socket and TCP connections, but treats + clients the same regardless of how they connect, those two connections are + equivalent post-connection but should have distinct GUIDs to distinguish + the kinds of connection. + + + + The intent of the GUID feature is to allow a client to avoid opening + multiple identical connections to the same server, by allowing the client + to check whether an address corresponds to an already-existing connection. + Comparing two addresses is insufficient, because addresses can be recycled + by distinct servers. + + [FIXME clarify if attempting to connect to each is a requirement or just a suggestion] -- cgit