Commit 7ce7502e authored by Havoc Pennington's avatar Havoc Pennington

2005-02-25 Havoc Pennington <hp@redhat.com>

	* 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
parent 1b5dace8
2005-02-25 Havoc Pennington <hp@redhat.com>
* 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 <walters@verbum.org>
* test/glib/Makefile.am (EXTRA_DIST): Add test-service-glib.xml
......
......@@ -27,6 +27,7 @@
#include "dbus-internals.h"
#include "dbus-message.h"
#include "dbus-marshal-validate.h"
#include "dbus-threads-internal.h"
#include <string.h>
/**
......
......@@ -21,7 +21,7 @@
*
*/
#include "dbus-dataslot.h"
#include "dbus-threads.h"
#include "dbus-threads-internal.h"
/**
* @defgroup DBusDataSlot Data slots
......
......@@ -33,7 +33,7 @@
#include <dbus/dbus-types.h>
#include <dbus/dbus-errors.h>
#include <dbus/dbus-sysdeps.h>
#include <dbus/dbus-threads.h>
#include <dbus/dbus-threads-internal.h>
DBUS_BEGIN_DECLS
......
......@@ -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
......
......@@ -32,6 +32,7 @@
#include "dbus-object-tree.h"
#include "dbus-memory.h"
#include "dbus-list.h"
#include "dbus-threads-internal.h"
#include <string.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 */
......
......@@ -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)
{
......
......@@ -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
*
......
......@@ -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*
......
......@@ -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);
}
/**
......
......@@ -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);
......
......@@ -2165,6 +2165,28 @@
The set of optionally-escaped bytes is intended to preserve address
readability and convenience.
</para>
<para>
A server may specify a key-value pair with the key <literal>guid</literal>
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.
</para>
<para>
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.
</para>
<para>
[FIXME clarify if attempting to connect to each is a requirement
or just a suggestion]
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment