Generate (hopefully) decent DDSI2.2-compliant GUID
Signed-off-by: Erik Boasson <eb@ilities.com>
This commit is contained in:
		
							parent
							
								
									a632f80000
								
							
						
					
					
						commit
						87398bdc98
					
				
					 3 changed files with 42 additions and 18 deletions
				
			
		| 
						 | 
				
			
			@ -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. */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue