From 87398bdc982d19c8b0b545f4961ebd1ce3023580 Mon Sep 17 00:00:00 2001 From: Erik Boasson Date: Sat, 24 Aug 2019 18:06:49 +0200 Subject: [PATCH] Generate (hopefully) decent DDSI2.2-compliant GUID Signed-off-by: Erik Boasson --- src/core/ddsi/include/dds/ddsi/q_globals.h | 2 +- src/core/ddsi/src/q_entity.c | 20 +++++------- src/core/ddsi/src/q_init.c | 38 +++++++++++++++++++--- 3 files changed, 42 insertions(+), 18 deletions(-) diff --git a/src/core/ddsi/include/dds/ddsi/q_globals.h b/src/core/ddsi/include/dds/ddsi/q_globals.h index 0d0f589..8458273 100644 --- a/src/core/ddsi/include/dds/ddsi/q_globals.h +++ b/src/core/ddsi/include/dds/ddsi/q_globals.h @@ -158,7 +158,7 @@ struct q_globals { /* GUID to be used in next call to new_participant; also protected by privileged_pp_lock */ - struct nn_guid next_ppguid; + struct nn_guid ppguid_base; /* number of up, non-loopback, IPv4/IPv6 interfaces, the index of the selected/preferred one, and the discovered interfaces. */ diff --git a/src/core/ddsi/src/q_entity.c b/src/core/ddsi/src/q_entity.c index 0c71cc0..1695eab 100644 --- a/src/core/ddsi/src/q_entity.c +++ b/src/core/ddsi/src/q_entity.c @@ -701,18 +701,14 @@ dds_return_t new_participant_guid (const nn_guid_t *ppguid, struct q_globals *gv dds_return_t new_participant (nn_guid_t *p_ppguid, struct q_globals *gv, unsigned flags, const nn_plist_t *plist) { - nn_guid_t ppguid; - - ddsrt_mutex_lock (&gv->privileged_pp_lock); - ppguid = gv->next_ppguid; - if (gv->next_ppguid.prefix.u[2]++ == ~0u) - { - ddsrt_mutex_unlock (&gv->privileged_pp_lock); - return DDS_RETCODE_OUT_OF_RESOURCES; - } - ddsrt_mutex_unlock (&gv->privileged_pp_lock); - *p_ppguid = ppguid; - + union { uint64_t u64; uint32_t u32[2]; } u; + u.u32[0] = gv->ppguid_base.prefix.u[1]; + u.u32[1] = gv->ppguid_base.prefix.u[2]; + u.u64 += ddsi_iid_gen (); + p_ppguid->prefix.u[0] = gv->ppguid_base.prefix.u[0]; + p_ppguid->prefix.u[1] = u.u32[0]; + p_ppguid->prefix.u[2] = u.u32[1]; + p_ppguid->entityid.u = NN_ENTITYID_PARTICIPANT; return new_participant_guid (p_ppguid, gv, flags, plist); } diff --git a/src/core/ddsi/src/q_init.c b/src/core/ddsi/src/q_init.c index 54601d9..0742c70 100644 --- a/src/core/ddsi/src/q_init.c +++ b/src/core/ddsi/src/q_init.c @@ -1033,11 +1033,39 @@ int rtps_init (struct q_globals *gv) ddsrt_mutex_init (&gv->privileged_pp_lock); gv->privileged_pp = NULL; - /* Template PP guid -- protected by privileged_pp_lock for simplicity */ - gv->next_ppguid.prefix.u[0] = locator_to_hopefully_unique_uint32 (&gv->ownloc); - gv->next_ppguid.prefix.u[1] = (unsigned) ddsrt_getpid (); - gv->next_ppguid.prefix.u[2] = 1; - gv->next_ppguid.entityid.u = NN_ENTITYID_PARTICIPANT; + /* Base participant GUID. IID initialisation should be from a really good random + generator and yield almost-unique numbers, and with a fallback of using process + id, timestamp and a counter, so incorporating that should do a lot to construct + a pseudo-random ID. (The assumption here is that feeding pseudo-random data in + MD5 will not change the randomness ...) Mix in the network configuration to + make machines with very reproducible boot sequences and low-resolution clocks + distinguishable. + + This base is kept constant, prefix.u[1] and prefix.u[2] are then treated as a + 64-bit unsigned integer to which we add IIDs to generate a hopping sequence + that won't repeat in the lifetime of the process. Seems like it ought to work + to keep the risks of collisions low. */ + { + uint64_t iid = toBE8u (ddsi_iid_gen ()); + ddsrt_md5_state_t st; + ddsrt_md5_byte_t digest[16]; + ddsrt_md5_init (&st); + ddsrt_md5_append (&st, (const ddsrt_md5_byte_t *) &iid, sizeof (iid)); + for (int i = 0; i < gv->n_interfaces; i++) + { + const struct nn_interface *intf = &gv->interfaces[i]; + ddsrt_md5_append (&st, (const ddsrt_md5_byte_t *) &intf->loc.kind, sizeof (intf->loc.kind)); + ddsrt_md5_append (&st, (const ddsrt_md5_byte_t *) intf->loc.address, sizeof (intf->loc.address)); + } + ddsrt_md5_finish (&st, digest); + /* DDSI 2.2 requires the first two bytes of the GUID to be set to the vendor + code -- a terrible waste of entropy ... */ + gv->ppguid_base.prefix.s[0] = NN_VENDORID_ECLIPSE.id[0]; + gv->ppguid_base.prefix.s[1] = NN_VENDORID_ECLIPSE.id[1]; + DDSRT_STATIC_ASSERT (sizeof (gv->ppguid_base.prefix.s) > 2 && sizeof (gv->ppguid_base.prefix.s) - 2 <= sizeof (digest)); + memcpy (&gv->ppguid_base.prefix.s[2], digest, sizeof (gv->ppguid_base.prefix.s) - 2); + gv->ppguid_base.entityid.u = NN_ENTITYID_PARTICIPANT; + } ddsrt_mutex_init (&gv->lock); ddsrt_mutex_init (&gv->spdp_lock);