2006-11-14 Havoc Pennington <hp@redhat.com>
authorHavoc Pennington <hp@redhat.com>
Wed, 15 Nov 2006 01:52:01 +0000 (01:52 +0000)
committerHavoc Pennington <hp@redhat.com>
Wed, 15 Nov 2006 01:52:01 +0000 (01:52 +0000)
* dbus/dbus-internals.c (_dbus_generate_uuid): The spec said the
UUID had the timestamp last, but the implementation had it first;
move it to last since I think it's a tiny bit nicer (easier to
compare at a glance, faster to sort, less code), and will not
cause any practical compatibility problems. Also, always convert
the timestamp to big endian.

* doc/dbus-specification.xml: Clean up the docs on the UUID.

* tools/dbus-uuidgen.1: more prominently say it is not suitable
as a replacement for regular uuidgen/RFC4122.

ChangeLog
dbus/dbus-connection.c
dbus/dbus-internals.c
dbus/dbus-internals.h
doc/dbus-specification.xml
tools/dbus-uuidgen.1

index 18ccccf..c189e7a 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+2006-11-14  Havoc Pennington  <hp@redhat.com>
+
+       * dbus/dbus-internals.c (_dbus_generate_uuid): The spec said the
+       UUID had the timestamp last, but the implementation had it first;
+       move it to last since I think it's a tiny bit nicer (easier to
+       compare at a glance, faster to sort, less code), and will not
+       cause any practical compatibility problems. Also, always convert
+       the timestamp to big endian.
+
+       * doc/dbus-specification.xml: Clean up the docs on the UUID.
+
+       * tools/dbus-uuidgen.1: more prominently say it is not suitable
+       as a replacement for regular uuidgen/RFC4122.
+
 2006-11-14  John (J5) Palmieri  <johnp@redhat.com>
 
        * dbus/dbus-threads.h: fix DBUS_THREAD_FUNCTIONS_ALL_MASK to have
index 552ecfd..268a97d 100644 (file)
@@ -5511,7 +5511,10 @@ dbus_connection_get_outgoing_size (DBusConnection *connection)
  * If the remote application has the same machine ID as the one
  * returned by this function, then the remote application is on the
  * same machine as your application.
- * 
+ *
+ * The UUID is not a UUID in the sense of RFC4122; the details
+ * are explained in the D-Bus specification.
+ *
  * @returns a 32-byte-long hex-encoded UUID string, or #NULL if insufficient memory
  */
 char*
index 961e726..788b352 100644 (file)
@@ -22,6 +22,7 @@
  */
 #include "dbus-internals.h"
 #include "dbus-protocol.h"
+#include "dbus-marshal-basic.h"
 #include "dbus-test.h"
 #include <stdio.h>
 #include <stdarg.h>
@@ -505,18 +506,12 @@ void
 _dbus_generate_uuid (DBusGUID *uuid)
 {
   long now;
-  char *p;
-  int ts_size;
 
   _dbus_get_current_time (&now, NULL);
 
-  uuid->as_uint32s[0] = now;
-
-  ts_size = sizeof (uuid->as_uint32s[0]);
-  p = ((char*)uuid->as_bytes) + ts_size;
+  uuid->as_uint32s[DBUS_UUID_LENGTH_WORDS - 1] = DBUS_UINT32_TO_BE (now);
   
-  _dbus_generate_random_bytes_buffer (p,
-                                      sizeof (uuid->as_bytes) - ts_size);
+  _dbus_generate_random_bytes_buffer (uuid->as_bytes, DBUS_UUID_LENGTH_BYTES - 4);
 }
 
 /**
index 4d83924..750882b 100644 (file)
@@ -318,7 +318,8 @@ void          _dbus_set_bad_address        (DBusError         *error,
                                             const char        *address_problem_other);
 
 #define DBUS_UUID_LENGTH_BYTES 16
-#define DBUS_UUID_LENGTH_HEX (DBUS_UUID_LENGTH_BYTES * 2)
+#define DBUS_UUID_LENGTH_WORDS (DBUS_UUID_LENGTH_BYTES / 4)
+#define DBUS_UUID_LENGTH_HEX   (DBUS_UUID_LENGTH_BYTES * 2)
 
 /**
  * A globally unique ID ; we have one for each DBusServer, and also one for each
@@ -326,7 +327,7 @@ void          _dbus_set_bad_address        (DBusError         *error,
  */
 union DBusGUID
 {
-  dbus_uint32_t as_uint32s[DBUS_UUID_LENGTH_BYTES / 4]; /**< guid as four uint32 values */
+  dbus_uint32_t as_uint32s[DBUS_UUID_LENGTH_WORDS];     /**< guid as four uint32 values */
   char as_bytes[DBUS_UUID_LENGTH_BYTES];                /**< guid as 16 single-byte values */
 };
 
index 986bada..77b7e69 100644 (file)
 
     <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.
+      and the value a hex-encoded 16-byte sequence. <xref linkend="uuids"/>
+      describes the format of the <literal>guid</literal> field.  If present,
+      this UUID may be used to distinguish one server address from another. A
+      server should use a different UUID 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 UUIDs 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.
+      The intent of the address UUID 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, and equivalent addresses may look
+      different if simply compared as strings (for example, the host in a TCP
+      address can be given as an IP address or as a hostname).
+    </para>
+
+    <para>
+      Note that the address key is <literal>guid</literal> even though the 
+      rest of the API and documentation says "UUID," for historical reasons.
     </para>
 
     <para>
       hyphens.
     </para>
   </sect1>
+
+  <sect1 id="uuids">
+    <title>UUIDs</title>
+    <para>
+      A working D-Bus implementation uses universally-unique IDs in two places.
+      First, each server address has a UUID identifying the address, 
+      as described in <xref linkend="addresses"/>. Second, each operating
+      system kernel instance running a D-Bus client or server has a UUID
+      identifying that kernel, retrieved by invoking the method
+      org.freedesktop.DBus.Peer.GetMachineId() (see <xref
+      linkend="standard-interfaces-peer"/>).
+    </para>
+    <para>
+      The term "UUID" in this document is intended literally, i.e. an
+      identifier that is universally unique. It is not intended to refer to
+      RFC4122, and in fact the D-Bus UUID is not compatible with that RFC.
+    </para>
+    <para>
+      The UUID must contain 128 bits of data and be hex-encoded.  The
+      hex-encoded string may not contain hyphens or other non-hex-digit
+      characters, and it must be exactly 32 characters long.  To generate a
+      UUID, the current reference implementation concatenates 96 bits of random
+      data followed by the 32-bit time in seconds since the UNIX epoch (in big
+      endian byte order).
+    </para>
+    <para>
+      It would also be acceptable and probably better to simply generate 128
+      bits of random data, as long as the random number generator is of high
+      quality. The timestamp could conceivably help if the random bits are not
+      very random. With a quality random number generator, collisions are
+      extremely unlikely even with only 96 bits, so it's somewhat academic.
+    </para>
+    <para>
+      Implementations should, however, stick to random data for the first 96 bits
+      of the UUID.
+    </para>
+  </sect1>
     
   <sect1 id="standard-interfaces">
     <title>Standard Interfaces</title>
         is more robust.
       </para>
       <para>
-        The UUID must contain 128 bits of data and be hex-encoded (meaning, the hex 
-        string contains 32 ASCII characters). The hex-encoded string may not contain 
-        hyphens or other non-hex-digit characters, and it must be exactly 32 characters long.
-        To generate a UUID, the recommended algorithm is to put the current time in seconds
-        since the UNIX epoch in the last 32 bits of the UUID, and to put randomly-generated bits
-        in the first 96 bits of the UUID.
+        <xref linkend="uuids"/> explains the format of the UUID.
       </para>
     </sect2>
 
index 882acfe..480fd18 100644 (file)
@@ -14,6 +14,11 @@ dbus-uuidgen \- Utility to generate UUIDs
 The \fIdbus-uuidgen\fP command generates or reads a universally unique ID.
 
 .PP
+Note that the D-Bus UUID has no relationship to RFC 4122 and does not generate
+UUIDs compatible with that spec. Many systems have a separate command
+for that (often called "uuidgen").
+
+.PP
 See http://www.freedesktop.org/software/dbus/ for more information
 about D-Bus.
 
@@ -39,15 +44,11 @@ IDs, and so forth.
 
 .PP
 If you run \fIdbus-uuidgen\fP with no options it just prints a new uuid made
-up out of thin air. This is similar to the regular "uuidgen" command.
-
-.PP
-If you run it with --get, it prints the machine uuid by default, or
-the uuid in the specified file if you specify a file.
+up out of thin air.
 
 .PP
-The D-Bus UUID has no relationship to RFC 4122 and does not generate
-UUIDs compatible with that spec.
+If you run it with --get, it prints the machine UUID by default, or
+the UUID in the specified file if you specify a file.
 
 .PP
 If you try to change an existing machine-id on a running system, it will
@@ -55,6 +56,10 @@ probably result in bad things happening. Don't try to change this file. Also,
 don't make it the same on two different systems; it needs to be different
 anytime there are two different kernels running.
 
+.PP
+The UUID should be different on two different virtual machines,
+because there are two different kernels.
+
 .SH OPTIONS
 The following options are supported:
 .TP