Make logging config per-domain
Signed-off-by: Erik Boasson <eb@ilities.com>
This commit is contained in:
		
							parent
							
								
									7190bb3d3e
								
							
						
					
					
						commit
						966ec0dda7
					
				
					 70 changed files with 2052 additions and 1718 deletions
				
			
		| 
						 | 
				
			
			@ -92,7 +92,7 @@ dds_topic_descriptor_t;
 | 
			
		|||
 | 
			
		||||
#define DDS_ANY_STATE (DDS_ANY_SAMPLE_STATE | DDS_ANY_VIEW_STATE | DDS_ANY_INSTANCE_STATE)
 | 
			
		||||
 | 
			
		||||
#define DDS_DOMAIN_DEFAULT -1
 | 
			
		||||
#define DDS_DOMAIN_DEFAULT ((uint32_t) 0xffffffffu)
 | 
			
		||||
#define DDS_HANDLE_NIL 0
 | 
			
		||||
#define DDS_ENTITY_NIL 0
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -113,7 +113,7 @@ typedef enum dds_entity_kind
 | 
			
		|||
 | 
			
		||||
/* Handles are opaque pointers to implementation types */
 | 
			
		||||
typedef uint64_t dds_instance_handle_t;
 | 
			
		||||
typedef int32_t dds_domainid_t;
 | 
			
		||||
typedef uint32_t dds_domainid_t;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* Topic encoding instruction types */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -19,8 +19,9 @@ extern "C" {
 | 
			
		|||
struct dds_rhc;
 | 
			
		||||
struct dds_reader;
 | 
			
		||||
struct ddsi_sertopic;
 | 
			
		||||
struct q_globals;
 | 
			
		||||
 | 
			
		||||
DDS_EXPORT struct dds_rhc *dds_rhc_default_new_xchecks (dds_reader *reader, struct ddsi_tkmap *tkmap, const struct ddsi_sertopic *topic, bool xchecks);
 | 
			
		||||
DDS_EXPORT struct dds_rhc *dds_rhc_default_new_xchecks (dds_reader *reader, struct q_globals *gv, const struct ddsi_sertopic *topic, bool xchecks);
 | 
			
		||||
DDS_EXPORT struct dds_rhc *dds_rhc_default_new (struct dds_reader *reader, const struct ddsi_sertopic *topic);
 | 
			
		||||
 | 
			
		||||
#if defined (__cplusplus)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -315,7 +315,6 @@ typedef struct dds_globals {
 | 
			
		|||
  int32_t m_init_count;
 | 
			
		||||
  ddsrt_avl_tree_t m_domains;
 | 
			
		||||
  ddsrt_mutex_t m_mutex;
 | 
			
		||||
 | 
			
		||||
  uint32_t threadmon_count;
 | 
			
		||||
  struct ddsi_threadmon *threadmon;
 | 
			
		||||
} dds_globals;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -87,7 +87,7 @@ void dds_string_free (char * str)
 | 
			
		|||
  dds_free (str);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void dds_sample_free_contents (char * data, const uint32_t * ops)
 | 
			
		||||
void dds_sample_free_contents (char *data, const uint32_t * ops)
 | 
			
		||||
{
 | 
			
		||||
  uint32_t op;
 | 
			
		||||
  uint32_t type;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -172,7 +172,7 @@ static struct ddsi_tkmap_instance *dds__builtin_get_tkmap_entry (const struct nn
 | 
			
		|||
  memcpy (&kh, guid, sizeof (kh));
 | 
			
		||||
  /* any random builtin topic will do (provided it has a GUID for a key), because what matters is the "class" of the topic, not the actual topic; also, this is called early in the initialisation of the entity with this GUID, which simply causes serdata_from_keyhash to create a key-only serdata because the key lookup fails. */
 | 
			
		||||
  sd = ddsi_serdata_from_keyhash (domain->builtin_participant_topic, &kh);
 | 
			
		||||
  tk = ddsi_tkmap_find (domain->gv.m_tkmap, sd, false, true);
 | 
			
		||||
  tk = ddsi_tkmap_find (domain->gv.m_tkmap, sd, true);
 | 
			
		||||
  ddsi_serdata_unref (sd);
 | 
			
		||||
  return tk;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -52,10 +52,10 @@ static dds_return_t dds_domain_init (dds_domain *domain, dds_domainid_t domain_i
 | 
			
		|||
  domain->gv.tstart = now ();
 | 
			
		||||
 | 
			
		||||
  (void) ddsrt_getenv ("CYCLONEDDS_URI", &uri);
 | 
			
		||||
  domain->cfgst = config_init (uri, &domain->gv.config);
 | 
			
		||||
  domain->cfgst = config_init (uri, &domain->gv.config, domain_id);
 | 
			
		||||
  if (domain->cfgst == NULL)
 | 
			
		||||
  {
 | 
			
		||||
    DDS_LOG (DDS_LC_CONFIG, "Failed to parse configuration XML file %s\n", uri);
 | 
			
		||||
    DDS_ILOG (DDS_LC_CONFIG, domain_id, "Failed to parse configuration XML file %s\n", uri);
 | 
			
		||||
    ret = DDS_RETCODE_ERROR;
 | 
			
		||||
    goto fail_config;
 | 
			
		||||
  }
 | 
			
		||||
| 
						 | 
				
			
			@ -63,9 +63,9 @@ static dds_return_t dds_domain_init (dds_domain *domain, dds_domainid_t domain_i
 | 
			
		|||
  /* if a domain id was explicitly given, check & fix up the configuration */
 | 
			
		||||
  if (domain_id != DDS_DOMAIN_DEFAULT)
 | 
			
		||||
  {
 | 
			
		||||
    if (domain_id < 0 || domain_id > 230)
 | 
			
		||||
    if (domain_id > 230)
 | 
			
		||||
    {
 | 
			
		||||
      DDS_ERROR ("requested domain id %"PRId32" is out of range\n", domain_id);
 | 
			
		||||
      DDS_ILOG (DDS_LC_ERROR, domain_id, "requested domain id %"PRIu32" is out of range\n", domain_id);
 | 
			
		||||
      ret = DDS_RETCODE_ERROR;
 | 
			
		||||
      goto fail_config_domainid;
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -75,7 +75,7 @@ static dds_return_t dds_domain_init (dds_domain *domain, dds_domainid_t domain_i
 | 
			
		|||
    }
 | 
			
		||||
    else if (domain_id != domain->gv.config.domainId.value)
 | 
			
		||||
    {
 | 
			
		||||
      DDS_ERROR ("requested domain id %"PRId32" is inconsistent with configured value %"PRId32"\n", domain_id, domain->gv.config.domainId.value);
 | 
			
		||||
      DDS_ILOG (DDS_LC_ERROR, domain_id, "requested domain id %"PRIu32" is inconsistent with configured value %"PRIu32"\n", domain_id, domain->gv.config.domainId.value);
 | 
			
		||||
      ret = DDS_RETCODE_ERROR;
 | 
			
		||||
      goto fail_config_domainid;
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -87,33 +87,42 @@ static dds_return_t dds_domain_init (dds_domain *domain, dds_domainid_t domain_i
 | 
			
		|||
 | 
			
		||||
  if (rtps_config_prep (&domain->gv, domain->cfgst) != 0)
 | 
			
		||||
  {
 | 
			
		||||
    DDS_LOG (DDS_LC_CONFIG, "Failed to configure RTPS\n");
 | 
			
		||||
    DDS_ILOG (DDS_LC_CONFIG, domain->m_id, "Failed to configure RTPS\n");
 | 
			
		||||
    ret = DDS_RETCODE_ERROR;
 | 
			
		||||
    goto fail_rtps_config;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /* Start monitoring the liveliness of all threads. */
 | 
			
		||||
  if (rtps_init (&domain->gv) < 0)
 | 
			
		||||
  {
 | 
			
		||||
    DDS_ILOG (DDS_LC_CONFIG, domain->m_id, "Failed to initialize RTPS\n");
 | 
			
		||||
    ret = DDS_RETCODE_ERROR;
 | 
			
		||||
    goto fail_rtps_init;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /* Start monitoring the liveliness of threads if this is the first
 | 
			
		||||
     domain to configured to do so. */
 | 
			
		||||
  if (domain->gv.config.liveliness_monitoring)
 | 
			
		||||
  {
 | 
			
		||||
    if (++dds_global.threadmon_count == 0)
 | 
			
		||||
    if (dds_global.threadmon_count++ == 0)
 | 
			
		||||
    {
 | 
			
		||||
      dds_global.threadmon = ddsi_threadmon_new (domain->gv.config.liveliness_monitoring_interval, domain->gv.config.noprogress_log_stacktraces);
 | 
			
		||||
      /* FIXME: configure settings */
 | 
			
		||||
      dds_global.threadmon = ddsi_threadmon_new (DDS_MSECS (333), true);
 | 
			
		||||
      if (dds_global.threadmon == NULL)
 | 
			
		||||
      {
 | 
			
		||||
        DDS_ERROR ("Failed to create a thread liveliness monitor\n");
 | 
			
		||||
        DDS_ILOG (DDS_LC_CONFIG, domain->m_id, "Failed to create a thread liveliness monitor\n");
 | 
			
		||||
        ret = DDS_RETCODE_OUT_OF_RESOURCES;
 | 
			
		||||
        goto fail_threadmon_new;
 | 
			
		||||
      }
 | 
			
		||||
      /* FIXME: thread properties */
 | 
			
		||||
      if (ddsi_threadmon_start (dds_global.threadmon, "threadmon") < 0)
 | 
			
		||||
      {
 | 
			
		||||
        DDS_ILOG (DDS_LC_ERROR, domain->m_id, "Failed to start the thread liveliness monitor\n");
 | 
			
		||||
        ret = DDS_RETCODE_ERROR;
 | 
			
		||||
        goto fail_threadmon_start;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (rtps_init (&domain->gv) < 0)
 | 
			
		||||
  {
 | 
			
		||||
    DDS_LOG (DDS_LC_CONFIG, "Failed to initialize RTPS\n");
 | 
			
		||||
    ret = DDS_RETCODE_ERROR;
 | 
			
		||||
    goto fail_rtps_init;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  dds__builtin_init (domain);
 | 
			
		||||
 | 
			
		||||
  if (rtps_start (&domain->gv) < 0)
 | 
			
		||||
| 
						 | 
				
			
			@ -123,17 +132,6 @@ static dds_return_t dds_domain_init (dds_domain *domain, dds_domainid_t domain_i
 | 
			
		|||
    goto fail_rtps_start;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (domain->gv.config.liveliness_monitoring && dds_global.threadmon_count == 1)
 | 
			
		||||
  {
 | 
			
		||||
    const char *name = "threadmon";
 | 
			
		||||
    if (ddsi_threadmon_start (dds_global.threadmon, name, lookup_thread_properties (&domain->gv.config, name)) < 0)
 | 
			
		||||
    {
 | 
			
		||||
      DDS_ERROR ("Failed to start the thread liveliness monitor\n");
 | 
			
		||||
      ret = DDS_RETCODE_ERROR;
 | 
			
		||||
      goto fail_threadmon_start;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /* Set additional default participant properties */
 | 
			
		||||
 | 
			
		||||
  char progname[50] = "UNKNOWN"; /* FIXME: once retrieving process names is back in */
 | 
			
		||||
| 
						 | 
				
			
			@ -153,26 +151,23 @@ static dds_return_t dds_domain_init (dds_domain *domain, dds_domainid_t domain_i
 | 
			
		|||
  (void) snprintf (domain->gv.default_plist_pp.entity_name, len, "%s<%u>", progname, domain->gv.default_plist_pp.process_id);
 | 
			
		||||
  domain->gv.default_plist_pp.present |= PP_ENTITY_NAME;
 | 
			
		||||
 | 
			
		||||
  if (domain->gv.config.liveliness_monitoring)
 | 
			
		||||
    ddsi_threadmon_register_domain (dds_global.threadmon, &domain->gv);
 | 
			
		||||
  return DDS_RETCODE_OK;
 | 
			
		||||
 | 
			
		||||
fail_threadmon_start:
 | 
			
		||||
  if (domain->gv.config.liveliness_monitoring && dds_global.threadmon_count == 1)
 | 
			
		||||
    ddsi_threadmon_stop (dds_global.threadmon);
 | 
			
		||||
  rtps_stop (&domain->gv);
 | 
			
		||||
fail_rtps_start:
 | 
			
		||||
  rtps_fini (&domain->gv);
 | 
			
		||||
fail_rtps_init:
 | 
			
		||||
  if (domain->gv.config.liveliness_monitoring)
 | 
			
		||||
  if (domain->gv.config.liveliness_monitoring && dds_global.threadmon_count == 1)
 | 
			
		||||
    ddsi_threadmon_stop (dds_global.threadmon);
 | 
			
		||||
fail_threadmon_start:
 | 
			
		||||
  if (domain->gv.config.liveliness_monitoring && --dds_global.threadmon_count == 0)
 | 
			
		||||
  {
 | 
			
		||||
    if (--dds_global.threadmon_count == 0)
 | 
			
		||||
    {
 | 
			
		||||
      ddsi_threadmon_free (dds_global.threadmon);
 | 
			
		||||
      dds_global.threadmon = NULL;
 | 
			
		||||
    }
 | 
			
		||||
    ddsi_threadmon_free (dds_global.threadmon);
 | 
			
		||||
    dds_global.threadmon = NULL;
 | 
			
		||||
  }
 | 
			
		||||
fail_threadmon_new:
 | 
			
		||||
  downgrade_main_thread ();
 | 
			
		||||
  thread_states_fini();
 | 
			
		||||
  rtps_fini (&domain->gv);
 | 
			
		||||
fail_rtps_init:
 | 
			
		||||
fail_rtps_config:
 | 
			
		||||
fail_config_domainid:
 | 
			
		||||
  config_fini (domain->cfgst);
 | 
			
		||||
| 
						 | 
				
			
			@ -182,19 +177,22 @@ fail_config:
 | 
			
		|||
 | 
			
		||||
static void dds_domain_fini (struct dds_domain *domain)
 | 
			
		||||
{
 | 
			
		||||
  if (domain->gv.config.liveliness_monitoring && dds_global.threadmon_count == 1)
 | 
			
		||||
    ddsi_threadmon_stop (dds_global.threadmon);
 | 
			
		||||
  rtps_stop (&domain->gv);
 | 
			
		||||
  dds__builtin_fini (domain);
 | 
			
		||||
  rtps_fini (&domain->gv);
 | 
			
		||||
 | 
			
		||||
  if (domain->gv.config.liveliness_monitoring)
 | 
			
		||||
    ddsi_threadmon_unregister_domain (dds_global.threadmon, &domain->gv);
 | 
			
		||||
 | 
			
		||||
  rtps_fini (&domain->gv);
 | 
			
		||||
 | 
			
		||||
  ddsrt_mutex_lock (&dds_global.m_mutex);
 | 
			
		||||
  if (domain->gv.config.liveliness_monitoring && --dds_global.threadmon_count == 0)
 | 
			
		||||
  {
 | 
			
		||||
    if (--dds_global.threadmon_count == 0)
 | 
			
		||||
    {
 | 
			
		||||
      ddsi_threadmon_free (dds_global.threadmon);
 | 
			
		||||
      dds_global.threadmon = NULL;
 | 
			
		||||
    }
 | 
			
		||||
    ddsi_threadmon_stop (dds_global.threadmon);
 | 
			
		||||
    ddsi_threadmon_free (dds_global.threadmon);
 | 
			
		||||
  }
 | 
			
		||||
  ddsrt_mutex_unlock (&dds_global.m_mutex);
 | 
			
		||||
 | 
			
		||||
  config_fini (domain->cfgst);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -208,9 +206,6 @@ dds_return_t dds_domain_create (dds_domain **domain_out, dds_domainid_t id)
 | 
			
		|||
  struct dds_domain *dom = NULL;
 | 
			
		||||
  dds_return_t ret;
 | 
			
		||||
 | 
			
		||||
  if (id != DDS_DOMAIN_DEFAULT && (id < 0 || id > 230))
 | 
			
		||||
    return DDS_RETCODE_BAD_PARAMETER;
 | 
			
		||||
 | 
			
		||||
  ddsrt_mutex_lock (&dds_global.m_mutex);
 | 
			
		||||
 | 
			
		||||
  /* FIXME: hack around default domain ids, not yet being able to handle multiple domains simultaneously */
 | 
			
		||||
| 
						 | 
				
			
			@ -246,7 +241,7 @@ dds_return_t dds_domain_create (dds_domain **domain_out, dds_domainid_t id)
 | 
			
		|||
      }
 | 
			
		||||
      break;
 | 
			
		||||
    case DDS_RETCODE_PRECONDITION_NOT_MET:
 | 
			
		||||
      DDS_ERROR("Inconsistent domain configuration detected: domain on configuration: %"PRId32", domain %"PRId32"\n", dom->m_id, id);
 | 
			
		||||
      DDS_ILOG (DDS_LC_ERROR, id, "Inconsistent domain configuration detected: domain on configuration: %"PRIu32", domain %"PRIu32"\n", dom->m_id, id);
 | 
			
		||||
      break;
 | 
			
		||||
  }
 | 
			
		||||
  ddsrt_mutex_unlock (&dds_global.m_mutex);
 | 
			
		||||
| 
						 | 
				
			
			@ -301,12 +296,14 @@ void dds_write_set_batch (bool enable)
 | 
			
		|||
{
 | 
			
		||||
  /* FIXME: get channels + latency budget working and get rid of this; in the mean time, any ugly hack will do.  */
 | 
			
		||||
  struct dds_domain *dom;
 | 
			
		||||
  dds_domainid_t last_id = -1;
 | 
			
		||||
  dds_domainid_t next_id = 0;
 | 
			
		||||
  dds_init ();
 | 
			
		||||
  ddsrt_mutex_lock (&dds_global.m_mutex);
 | 
			
		||||
  while ((dom = ddsrt_avl_lookup_succ (&dds_domaintree_def, &dds_global.m_domains, &last_id)) != NULL)
 | 
			
		||||
  while ((dom = ddsrt_avl_lookup_succ_eq (&dds_domaintree_def, &dds_global.m_domains, &next_id)) != NULL)
 | 
			
		||||
  {
 | 
			
		||||
    last_id = dom->m_id;
 | 
			
		||||
    /* Must be sure that the compiler doesn't reload curr_id from dom->m_id */
 | 
			
		||||
    dds_domainid_t curr_id = *((volatile dds_domainid_t *) &dom->m_id);
 | 
			
		||||
    next_id = curr_id + 1;
 | 
			
		||||
    dom->gv.config.whc_batch = enable;
 | 
			
		||||
 | 
			
		||||
    dds_instance_handle_t last_iid = 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -322,7 +319,7 @@ void dds_write_set_batch (bool enable)
 | 
			
		|||
      pushdown_set_batch (e, enable);
 | 
			
		||||
      ddsrt_mutex_lock (&dds_global.m_mutex);
 | 
			
		||||
      dds_entity_unpin (e);
 | 
			
		||||
      dom = ddsrt_avl_lookup (&dds_domaintree_def, &dds_global.m_domains, &last_id);
 | 
			
		||||
      dom = ddsrt_avl_lookup (&dds_domaintree_def, &dds_global.m_domains, &curr_id);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  ddsrt_mutex_unlock (&dds_global.m_mutex);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -201,10 +201,7 @@ dds_return_t dds_delete_impl (dds_entity_t entity, bool keep_if_explicit)
 | 
			
		|||
  dds_return_t rc;
 | 
			
		||||
 | 
			
		||||
  if ((rc = dds_entity_pin (entity, &e)) < 0)
 | 
			
		||||
  {
 | 
			
		||||
    DDS_TRACE ("dds_delete_impl: error on locking entity %"PRIu32" keep_if_explicit %d\n", entity, (int) keep_if_explicit);
 | 
			
		||||
    return rc;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  ddsrt_mutex_lock (&e->m_mutex);
 | 
			
		||||
  if (keep_if_explicit == true && (e->m_flags & DDS_ENTITY_IMPLICIT) == 0)
 | 
			
		||||
| 
						 | 
				
			
			@ -460,7 +457,7 @@ static dds_return_t dds_set_qos_locked_impl (dds_entity *e, const dds_qos_t *qos
 | 
			
		|||
  dds_qos_t *newqos = dds_create_qos ();
 | 
			
		||||
  nn_xqos_mergein_missing (newqos, qos, mask);
 | 
			
		||||
  nn_xqos_mergein_missing (newqos, e->m_qos, ~(uint64_t)0);
 | 
			
		||||
  if ((ret = nn_xqos_valid (newqos)) != DDS_RETCODE_OK)
 | 
			
		||||
  if ((ret = nn_xqos_valid (&e->m_domain->gv.logconfig, newqos)) != DDS_RETCODE_OK)
 | 
			
		||||
    ; /* oops ... invalid or inconsistent */
 | 
			
		||||
  else if (!(e->m_flags & DDS_ENTITY_ENABLED))
 | 
			
		||||
    ; /* do as you please while the entity is not enabled (perhaps we should even allow invalid ones?) */
 | 
			
		||||
| 
						 | 
				
			
			@ -823,16 +820,16 @@ dds_return_t dds_enable (dds_entity_t entity)
 | 
			
		|||
  dds_entity *e;
 | 
			
		||||
  dds_return_t rc;
 | 
			
		||||
 | 
			
		||||
  if ((rc = dds_entity_lock(entity, DDS_KIND_DONTCARE, &e)) != DDS_RETCODE_OK)
 | 
			
		||||
  if ((rc = dds_entity_lock (entity, DDS_KIND_DONTCARE, &e)) != DDS_RETCODE_OK)
 | 
			
		||||
    return rc;
 | 
			
		||||
 | 
			
		||||
  if ((e->m_flags & DDS_ENTITY_ENABLED) == 0)
 | 
			
		||||
  {
 | 
			
		||||
    /* TODO: Really enable. */
 | 
			
		||||
    e->m_flags |= DDS_ENTITY_ENABLED;
 | 
			
		||||
    DDS_ERROR ("Delayed entity enabling is not supported\n");
 | 
			
		||||
    DDS_CERROR (&e->m_domain->gv.logconfig, "Delayed entity enabling is not supported\n");
 | 
			
		||||
  }
 | 
			
		||||
  dds_entity_unlock(e);
 | 
			
		||||
  dds_entity_unlock (e);
 | 
			
		||||
  return DDS_RETCODE_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -58,7 +58,7 @@ dds_return_t dds_init (void)
 | 
			
		|||
 | 
			
		||||
  if (dds_handle_server_init () != DDS_RETCODE_OK)
 | 
			
		||||
  {
 | 
			
		||||
    DDS_ERROR("Failed to initialize internal handle server\n");
 | 
			
		||||
    DDS_ERROR ("Failed to initialize internal handle server\n");
 | 
			
		||||
    ret = DDS_RETCODE_ERROR;
 | 
			
		||||
    goto fail_handleserver;
 | 
			
		||||
  }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -41,7 +41,7 @@ dds_return_t dds_dispose_ih (dds_entity_t writer, dds_instance_handle_t handle)
 | 
			
		|||
static struct ddsi_tkmap_instance *dds_instance_find (const dds_topic *topic, const void *data, const bool create)
 | 
			
		||||
{
 | 
			
		||||
  struct ddsi_serdata *sd = ddsi_serdata_from_sample (topic->m_stopic, SDK_KEY, data);
 | 
			
		||||
  struct ddsi_tkmap_instance *inst = ddsi_tkmap_find (topic->m_entity.m_domain->gv.m_tkmap, sd, false, create);
 | 
			
		||||
  struct ddsi_tkmap_instance *inst = ddsi_tkmap_find (topic->m_entity.m_domain->gv.m_tkmap, sd, create);
 | 
			
		||||
  ddsi_serdata_unref (sd);
 | 
			
		||||
  return inst;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -41,7 +41,7 @@ static dds_return_t dds_participant_delete (dds_entity *e)
 | 
			
		|||
 | 
			
		||||
  thread_state_awake (lookup_thread_state (), &e->m_domain->gv);
 | 
			
		||||
  if ((ret = delete_participant (&e->m_domain->gv, &e->m_guid)) < 0)
 | 
			
		||||
    DDS_ERROR ("dds_participant_delete: internal error %"PRId32"\n", ret);
 | 
			
		||||
    DDS_CERROR (&e->m_domain->gv.logconfig, "dds_participant_delete: internal error %"PRId32"\n", ret);
 | 
			
		||||
  ddsrt_mutex_lock (&dds_global.m_mutex);
 | 
			
		||||
  ddsrt_avl_delete (&dds_entity_children_td, &e->m_domain->m_ppants, e);
 | 
			
		||||
  ddsrt_mutex_unlock (&dds_global.m_mutex);
 | 
			
		||||
| 
						 | 
				
			
			@ -100,7 +100,7 @@ dds_entity_t dds_create_participant (const dds_domainid_t domain, const dds_qos_
 | 
			
		|||
  if (qos != NULL)
 | 
			
		||||
    nn_xqos_mergein_missing (new_qos, qos, DDS_PARTICIPANT_QOS_MASK);
 | 
			
		||||
  nn_xqos_mergein_missing (new_qos, &dom->gv.default_plist_pp.qos, ~(uint64_t)0);
 | 
			
		||||
  if ((ret = nn_xqos_valid (new_qos)) < 0)
 | 
			
		||||
  if ((ret = nn_xqos_valid (&dom->gv.logconfig, new_qos)) < 0)
 | 
			
		||||
    goto err_qos_validation;
 | 
			
		||||
 | 
			
		||||
  /* Translate qos */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -59,7 +59,7 @@ dds_entity_t dds_create_publisher (dds_entity_t participant, const dds_qos_t *qo
 | 
			
		|||
  if (qos)
 | 
			
		||||
    nn_xqos_mergein_missing (new_qos, qos, DDS_PUBLISHER_QOS_MASK);
 | 
			
		||||
  nn_xqos_mergein_missing (new_qos, &par->m_entity.m_domain->gv.default_xqos_pub, ~(uint64_t)0);
 | 
			
		||||
  if ((ret = nn_xqos_valid (new_qos)) != DDS_RETCODE_OK)
 | 
			
		||||
  if ((ret = nn_xqos_valid (&par->m_entity.m_domain->gv.logconfig, new_qos)) != DDS_RETCODE_OK)
 | 
			
		||||
  {
 | 
			
		||||
    dds_participant_unlock (par);
 | 
			
		||||
    return ret;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -361,7 +361,7 @@ dds_entity_t dds_create_reader (dds_entity_t participant_or_subscriber, dds_enti
 | 
			
		|||
    nn_xqos_mergein_missing (rqos, tp->m_entity.m_qos, ~(uint64_t)0);
 | 
			
		||||
  nn_xqos_mergein_missing (rqos, &sub->m_entity.m_domain->gv.default_xqos_rd, ~(uint64_t)0);
 | 
			
		||||
 | 
			
		||||
  if ((ret = nn_xqos_valid (rqos)) != DDS_RETCODE_OK)
 | 
			
		||||
  if ((ret = nn_xqos_valid (&sub->m_entity.m_domain->gv.logconfig, rqos)) != DDS_RETCODE_OK)
 | 
			
		||||
  {
 | 
			
		||||
    dds_delete_qos (rqos);
 | 
			
		||||
    reader = ret;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -159,7 +159,7 @@
 | 
			
		|||
 | 
			
		||||
#define INCLUDE_TRACE 1
 | 
			
		||||
#if INCLUDE_TRACE
 | 
			
		||||
#define TRACE(...) DDS_LOG(DDS_LC_RHC, __VA_ARGS__)
 | 
			
		||||
#define TRACE(...) DDS_CLOG (DDS_LC_RHC, &rhc->gv->logconfig, __VA_ARGS__)
 | 
			
		||||
#else
 | 
			
		||||
#define TRACE(...) ((void)0)
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			@ -306,6 +306,7 @@ struct dds_rhc_default {
 | 
			
		|||
 | 
			
		||||
  dds_reader *reader;                /* reader -- may be NULL (used by rhc_torture) */
 | 
			
		||||
  struct ddsi_tkmap *tkmap;          /* back pointer to tkmap */
 | 
			
		||||
  struct q_globals *gv;              /* globals -- so far only for log config */
 | 
			
		||||
  const struct ddsi_sertopic *topic; /* topic description */
 | 
			
		||||
  uint32_t history_depth;            /* depth, 1 for KEEP_LAST_1, 2**32-1 for KEEP_ALL */
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -523,7 +524,7 @@ static void remove_inst_from_nonempty_list (struct dds_rhc_default *rhc, struct
 | 
			
		|||
  rhc->n_nonempty_instances--;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct dds_rhc *dds_rhc_default_new_xchecks (dds_reader *reader, struct ddsi_tkmap *tkmap, const struct ddsi_sertopic *topic, bool xchecks)
 | 
			
		||||
struct dds_rhc *dds_rhc_default_new_xchecks (dds_reader *reader, struct q_globals *gv, const struct ddsi_sertopic *topic, bool xchecks)
 | 
			
		||||
{
 | 
			
		||||
  struct dds_rhc_default *rhc = ddsrt_malloc (sizeof (*rhc));
 | 
			
		||||
  memset (rhc, 0, sizeof (*rhc));
 | 
			
		||||
| 
						 | 
				
			
			@ -534,7 +535,8 @@ struct dds_rhc *dds_rhc_default_new_xchecks (dds_reader *reader, struct ddsi_tkm
 | 
			
		|||
  rhc->instances = ddsrt_hh_new (1, instance_iid_hash, instance_iid_eq);
 | 
			
		||||
  rhc->topic = topic;
 | 
			
		||||
  rhc->reader = reader;
 | 
			
		||||
  rhc->tkmap = tkmap;
 | 
			
		||||
  rhc->tkmap = gv->m_tkmap;
 | 
			
		||||
  rhc->gv = gv;
 | 
			
		||||
  rhc->xchecks = xchecks;
 | 
			
		||||
 | 
			
		||||
  return &rhc->common;
 | 
			
		||||
| 
						 | 
				
			
			@ -542,7 +544,7 @@ struct dds_rhc *dds_rhc_default_new_xchecks (dds_reader *reader, struct ddsi_tkm
 | 
			
		|||
 | 
			
		||||
struct dds_rhc *dds_rhc_default_new (dds_reader *reader, const struct ddsi_sertopic *topic)
 | 
			
		||||
{
 | 
			
		||||
  return dds_rhc_default_new_xchecks (reader, reader->m_entity.m_domain->gv.m_tkmap, topic, (reader->m_entity.m_domain->gv.config.enabled_xchecks & DDS_XCHECK_RHC) != 0);
 | 
			
		||||
  return dds_rhc_default_new_xchecks (reader, &reader->m_entity.m_domain->gv, topic, (reader->m_entity.m_domain->gv.config.enabled_xchecks & DDS_XCHECK_RHC) != 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void dds_rhc_default_set_qos (struct dds_rhc_default * rhc, const dds_qos_t * qos)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -252,9 +252,7 @@ static size_t dds_stream_check_optimize1 (const dds_topic_descriptor_t * __restr
 | 
			
		|||
 | 
			
		||||
size_t dds_stream_check_optimize (const dds_topic_descriptor_t * __restrict desc)
 | 
			
		||||
{
 | 
			
		||||
  const size_t size = dds_stream_check_optimize1 (desc);
 | 
			
		||||
  DDS_TRACE ("Marshalling for type: %s is %soptimised\n", desc->m_typename, size ? "" : "not ");
 | 
			
		||||
  return size;
 | 
			
		||||
  return dds_stream_check_optimize1 (desc);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static char *dds_stream_reuse_string (dds_istream_t * __restrict is, char * __restrict str, const uint32_t bound)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -56,7 +56,7 @@ dds_entity_t dds__create_subscriber_l (dds_participant *participant, const dds_q
 | 
			
		|||
  if (qos)
 | 
			
		||||
    nn_xqos_mergein_missing (new_qos, qos, DDS_SUBSCRIBER_QOS_MASK);
 | 
			
		||||
  nn_xqos_mergein_missing (new_qos, &participant->m_entity.m_domain->gv.default_xqos_sub, ~(uint64_t)0);
 | 
			
		||||
  if ((ret = nn_xqos_valid (new_qos)) != DDS_RETCODE_OK)
 | 
			
		||||
  if ((ret = nn_xqos_valid (&participant->m_entity.m_domain->gv.logconfig, new_qos)) != DDS_RETCODE_OK)
 | 
			
		||||
  {
 | 
			
		||||
    dds_delete_qos (new_qos);
 | 
			
		||||
    return ret;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -291,6 +291,12 @@ dds_entity_t dds_create_topic_arbitrary (dds_entity_t participant, struct ddsi_s
 | 
			
		|||
  if (sertopic == NULL)
 | 
			
		||||
    return DDS_RETCODE_BAD_PARAMETER;
 | 
			
		||||
 | 
			
		||||
  /* Claim participant handle so we can be sure the handle will not be
 | 
			
		||||
     reused if we temporarily unlock the participant to check the an
 | 
			
		||||
     existing topic's compatibility */
 | 
			
		||||
  if ((rc = dds_entity_pin (participant, &par_ent)) < 0)
 | 
			
		||||
    return rc;
 | 
			
		||||
 | 
			
		||||
  new_qos = dds_create_qos ();
 | 
			
		||||
  if (qos)
 | 
			
		||||
    nn_xqos_mergein_missing (new_qos, qos, DDS_TOPIC_QOS_MASK);
 | 
			
		||||
| 
						 | 
				
			
			@ -305,15 +311,9 @@ dds_entity_t dds_create_topic_arbitrary (dds_entity_t participant, struct ddsi_s
 | 
			
		|||
   * Leaving the topic QoS sparse means a default-default topic QoS of
 | 
			
		||||
   * best-effort will do "the right thing" and let a writer still default to
 | 
			
		||||
   * reliable ... (and keep behaviour unchanged) */
 | 
			
		||||
  if ((rc = nn_xqos_valid (new_qos)) != DDS_RETCODE_OK)
 | 
			
		||||
  if ((rc = nn_xqos_valid (&par_ent->m_domain->gv.logconfig, new_qos)) != DDS_RETCODE_OK)
 | 
			
		||||
    goto err_invalid_qos;
 | 
			
		||||
 | 
			
		||||
  /* Claim participant handle so we can be sure the handle will not be
 | 
			
		||||
     reused if we temporarily unlock the participant to check the an
 | 
			
		||||
     existing topic's compatibility */
 | 
			
		||||
  if ((rc = dds_entity_pin (participant, &par_ent)) < 0)
 | 
			
		||||
    goto err_claim_participant;
 | 
			
		||||
 | 
			
		||||
  /* FIXME: just mutex_lock ought to be good enough, but there is the
 | 
			
		||||
     pesky "closed" check still ... */
 | 
			
		||||
  if ((rc = dds_participant_lock (participant, &par)) != DDS_RETCODE_OK)
 | 
			
		||||
| 
						 | 
				
			
			@ -446,10 +446,9 @@ dds_entity_t dds_create_topic_arbitrary (dds_entity_t participant, struct ddsi_s
 | 
			
		|||
err_sertopic_reuse:
 | 
			
		||||
  dds_participant_unlock (par);
 | 
			
		||||
err_lock_participant:
 | 
			
		||||
  dds_entity_unpin (par_ent);
 | 
			
		||||
err_claim_participant:
 | 
			
		||||
err_invalid_qos:
 | 
			
		||||
  dds_delete_qos (new_qos);
 | 
			
		||||
  dds_entity_unpin (par_ent);
 | 
			
		||||
  return rc;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -494,6 +493,7 @@ dds_entity_t dds_create_topic (dds_entity_t participant, const dds_topic_descrip
 | 
			
		|||
  /* Check if topic cannot be optimised (memcpy marshal) */
 | 
			
		||||
  if (!(desc->m_flagset & DDS_TOPIC_NO_OPTIMIZE)) {
 | 
			
		||||
    st->opt_size = dds_stream_check_optimize (desc);
 | 
			
		||||
    DDS_CTRACE (&ppent->m_domain->gv.logconfig, "Marshalling for type: %s is %soptimised\n", desc->m_typename, st->opt_size ? "" : "not ");
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  nn_plist_init_empty (&plist);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -80,6 +80,7 @@ struct whc_impl {
 | 
			
		|||
  uint64_t total_bytes; /* total number of bytes pushed in */
 | 
			
		||||
  unsigned is_transient_local: 1;
 | 
			
		||||
  unsigned xchecks: 1;
 | 
			
		||||
  struct q_globals *gv;
 | 
			
		||||
  struct ddsi_tkmap *tkmap;
 | 
			
		||||
  uint32_t hdepth; /* 0 = unlimited */
 | 
			
		||||
  uint32_t tldepth; /* 0 = disabled/unlimited (no need to maintain an index if KEEP_ALL <=> is_transient_local + tldepth=0) */
 | 
			
		||||
| 
						 | 
				
			
			@ -138,7 +139,7 @@ static bool whc_default_sample_iter_borrow_next (struct whc_sample_iter *opaque_
 | 
			
		|||
static void whc_default_free (struct whc *whc);
 | 
			
		||||
 | 
			
		||||
static const ddsrt_avl_treedef_t whc_seq_treedef =
 | 
			
		||||
DDSRT_AVL_TREEDEF_INITIALIZER (offsetof (struct whc_intvnode, avlnode), offsetof (struct whc_intvnode, min), compare_seq, 0);
 | 
			
		||||
  DDSRT_AVL_TREEDEF_INITIALIZER (offsetof (struct whc_intvnode, avlnode), offsetof (struct whc_intvnode, min), compare_seq, 0);
 | 
			
		||||
 | 
			
		||||
static const struct whc_ops whc_ops = {
 | 
			
		||||
  .insert = whc_default_insert,
 | 
			
		||||
| 
						 | 
				
			
			@ -155,6 +156,8 @@ static const struct whc_ops whc_ops = {
 | 
			
		|||
  .free = whc_default_free
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#define TRACE(...) DDS_CLOG (DDS_LC_WHC, &whc->gv->logconfig, __VA_ARGS__)
 | 
			
		||||
 | 
			
		||||
/* Number of instantiated WHCs and a global freelist for WHC nodes that gets
 | 
			
		||||
 initialized lazily and cleaned up automatically when the last WHC is freed.
 | 
			
		||||
 Protected by dds_global.m_mutex.
 | 
			
		||||
| 
						 | 
				
			
			@ -359,6 +362,7 @@ struct whc *whc_new (struct q_globals *gv, int is_transient_local, uint32_t hdep
 | 
			
		|||
  ddsrt_mutex_init (&whc->lock);
 | 
			
		||||
  whc->is_transient_local = is_transient_local ? 1 : 0;
 | 
			
		||||
  whc->xchecks = (gv->config.enabled_xchecks & DDS_XCHECK_WHC) != 0;
 | 
			
		||||
  whc->gv = gv;
 | 
			
		||||
  whc->tkmap = gv->m_tkmap;
 | 
			
		||||
  whc->hdepth = hdepth;
 | 
			
		||||
  whc->tldepth = tldepth;
 | 
			
		||||
| 
						 | 
				
			
			@ -572,7 +576,7 @@ static void free_one_instance_from_idx (struct whc_impl *whc, seqno_t max_drop_s
 | 
			
		|||
      oldn->idxnode = NULL;
 | 
			
		||||
      if (oldn->seq <= max_drop_seq)
 | 
			
		||||
      {
 | 
			
		||||
        DDS_LOG (DDS_LC_WHC, "  prune tl whcn %p\n", (void *)oldn);
 | 
			
		||||
        TRACE ("  prune tl whcn %p\n", (void *)oldn);
 | 
			
		||||
        assert (oldn != whc->maxseq_node);
 | 
			
		||||
        whc_delete_one (whc, oldn);
 | 
			
		||||
      }
 | 
			
		||||
| 
						 | 
				
			
			@ -886,7 +890,7 @@ static uint32_t whc_default_remove_acked_messages_full (struct whc_impl *whc, se
 | 
			
		|||
  if (whc->is_transient_local && whc->tldepth == 0)
 | 
			
		||||
  {
 | 
			
		||||
    /* KEEP_ALL on transient local, so we can never ever delete anything */
 | 
			
		||||
    DDS_LOG (DDS_LC_WHC, "  KEEP_ALL transient-local: do nothing\n");
 | 
			
		||||
    TRACE ("  KEEP_ALL transient-local: do nothing\n");
 | 
			
		||||
    *deferred_free_list = NULL;
 | 
			
		||||
    return 0;
 | 
			
		||||
  }
 | 
			
		||||
| 
						 | 
				
			
			@ -896,11 +900,11 @@ static uint32_t whc_default_remove_acked_messages_full (struct whc_impl *whc, se
 | 
			
		|||
  prev_seq = whcn ? whcn->prev_seq : NULL;
 | 
			
		||||
  while (whcn && whcn->seq <= max_drop_seq)
 | 
			
		||||
  {
 | 
			
		||||
    DDS_LOG (DDS_LC_WHC, "  whcn %p %"PRId64, (void *) whcn, whcn->seq);
 | 
			
		||||
    TRACE ("  whcn %p %"PRId64, (void *) whcn, whcn->seq);
 | 
			
		||||
    if (whcn_in_tlidx (whc, whcn->idxnode, whcn->idxnode_pos))
 | 
			
		||||
    {
 | 
			
		||||
      /* quickly skip over samples in tlidx */
 | 
			
		||||
      DDS_LOG (DDS_LC_WHC, " tl:keep");
 | 
			
		||||
      TRACE (" tl:keep");
 | 
			
		||||
      if (whcn->unacked)
 | 
			
		||||
      {
 | 
			
		||||
        assert (whc->unacked_bytes >= whcn->size);
 | 
			
		||||
| 
						 | 
				
			
			@ -918,13 +922,13 @@ static uint32_t whc_default_remove_acked_messages_full (struct whc_impl *whc, se
 | 
			
		|||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
      DDS_LOG (DDS_LC_WHC, " delete");
 | 
			
		||||
      TRACE (" delete");
 | 
			
		||||
      last_to_free->next_seq = whcn;
 | 
			
		||||
      last_to_free = last_to_free->next_seq;
 | 
			
		||||
      whc_delete_one_intv (whc, &intv, &whcn);
 | 
			
		||||
      ndropped++;
 | 
			
		||||
    }
 | 
			
		||||
    DDS_LOG (DDS_LC_WHC, "\n");
 | 
			
		||||
    TRACE ("\n");
 | 
			
		||||
  }
 | 
			
		||||
  if (prev_seq)
 | 
			
		||||
    prev_seq->next_seq = whcn;
 | 
			
		||||
| 
						 | 
				
			
			@ -941,7 +945,7 @@ static uint32_t whc_default_remove_acked_messages_full (struct whc_impl *whc, se
 | 
			
		|||
  if (whc->tldepth > 0 && whc->idxdepth > whc->tldepth)
 | 
			
		||||
  {
 | 
			
		||||
    assert (whc->hdepth == whc->idxdepth);
 | 
			
		||||
    DDS_LOG (DDS_LC_WHC, "  idxdepth %"PRIu32" > tldepth %"PRIu32" > 0 -- must prune\n", whc->idxdepth, whc->tldepth);
 | 
			
		||||
    TRACE ("  idxdepth %"PRIu32" > tldepth %"PRIu32" > 0 -- must prune\n", whc->idxdepth, whc->tldepth);
 | 
			
		||||
 | 
			
		||||
    /* Do a second pass over the sequence number range we just processed: this time we only
 | 
			
		||||
     encounter samples that were retained because of the transient-local durability setting
 | 
			
		||||
| 
						 | 
				
			
			@ -952,14 +956,14 @@ static uint32_t whc_default_remove_acked_messages_full (struct whc_impl *whc, se
 | 
			
		|||
      struct whc_idxnode * const idxn = whcn->idxnode;
 | 
			
		||||
      uint32_t cnt, idx;
 | 
			
		||||
 | 
			
		||||
      DDS_LOG (DDS_LC_WHC, "  whcn %p %"PRId64" idxn %p prune_seq %"PRId64":", (void *) whcn, whcn->seq, (void *) idxn, idxn->prune_seq);
 | 
			
		||||
      TRACE ("  whcn %p %"PRId64" idxn %p prune_seq %"PRId64":", (void *) whcn, whcn->seq, (void *) idxn, idxn->prune_seq);
 | 
			
		||||
 | 
			
		||||
      assert (whcn_in_tlidx (whc, idxn, whcn->idxnode_pos));
 | 
			
		||||
      assert (idxn->prune_seq <= max_drop_seq);
 | 
			
		||||
 | 
			
		||||
      if (idxn->prune_seq == max_drop_seq)
 | 
			
		||||
      {
 | 
			
		||||
        DDS_LOG (DDS_LC_WHC, " already pruned\n");
 | 
			
		||||
        TRACE (" already pruned\n");
 | 
			
		||||
        whcn = whcn->next_seq;
 | 
			
		||||
        continue;
 | 
			
		||||
      }
 | 
			
		||||
| 
						 | 
				
			
			@ -987,7 +991,7 @@ static uint32_t whc_default_remove_acked_messages_full (struct whc_impl *whc, se
 | 
			
		|||
          whcn_template.serdata = ddsi_serdata_ref (oldn->serdata);
 | 
			
		||||
          assert (oldn->seq < whcn->seq);
 | 
			
		||||
#endif
 | 
			
		||||
          DDS_LOG (DDS_LC_WHC, " del %p %"PRId64, (void *) oldn, oldn->seq);
 | 
			
		||||
          TRACE (" del %p %"PRId64, (void *) oldn, oldn->seq);
 | 
			
		||||
          whc_delete_one (whc, oldn);
 | 
			
		||||
#ifndef NDEBUG
 | 
			
		||||
          assert (ddsrt_hh_lookup (whc->idx_hash, &template) == idxn);
 | 
			
		||||
| 
						 | 
				
			
			@ -995,7 +999,7 @@ static uint32_t whc_default_remove_acked_messages_full (struct whc_impl *whc, se
 | 
			
		|||
#endif
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      DDS_LOG (DDS_LC_WHC, "\n");
 | 
			
		||||
      TRACE ("\n");
 | 
			
		||||
      whcn = whcn->next_seq;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
| 
						 | 
				
			
			@ -1018,13 +1022,13 @@ static uint32_t whc_default_remove_acked_messages (struct whc *whc_generic, seqn
 | 
			
		|||
  assert (max_drop_seq < MAX_SEQ_NUMBER);
 | 
			
		||||
  assert (max_drop_seq >= whc->max_drop_seq);
 | 
			
		||||
 | 
			
		||||
  if (dds_get_log_mask () & DDS_LC_WHC)
 | 
			
		||||
  if (whc->gv->logconfig.c.mask & DDS_LC_WHC)
 | 
			
		||||
  {
 | 
			
		||||
    struct whc_state tmp;
 | 
			
		||||
    get_state_locked (whc, &tmp);
 | 
			
		||||
    DDS_LOG (DDS_LC_WHC, "whc_default_remove_acked_messages(%p max_drop_seq %"PRId64")\n", (void *)whc, max_drop_seq);
 | 
			
		||||
    DDS_LOG (DDS_LC_WHC, "  whc: [%"PRId64",%"PRId64"] max_drop_seq %"PRId64" h %"PRIu32" tl %"PRIu32"\n",
 | 
			
		||||
             tmp.min_seq, tmp.max_seq, whc->max_drop_seq, whc->hdepth, whc->tldepth);
 | 
			
		||||
    TRACE ("whc_default_remove_acked_messages(%p max_drop_seq %"PRId64")\n", (void *)whc, max_drop_seq);
 | 
			
		||||
    TRACE ("  whc: [%"PRId64",%"PRId64"] max_drop_seq %"PRId64" h %"PRIu32" tl %"PRIu32"\n",
 | 
			
		||||
           tmp.min_seq, tmp.max_seq, whc->max_drop_seq, whc->hdepth, whc->tldepth);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  check_whc (whc);
 | 
			
		||||
| 
						 | 
				
			
			@ -1112,14 +1116,14 @@ static int whc_default_insert (struct whc *whc_generic, seqno_t max_drop_seq, se
 | 
			
		|||
  ddsrt_mutex_lock (&whc->lock);
 | 
			
		||||
  check_whc (whc);
 | 
			
		||||
 | 
			
		||||
  if (dds_get_log_mask () & DDS_LC_WHC)
 | 
			
		||||
  if (whc->gv->logconfig.c.mask & DDS_LC_WHC)
 | 
			
		||||
  {
 | 
			
		||||
    struct whc_state whcst;
 | 
			
		||||
    get_state_locked (whc, &whcst);
 | 
			
		||||
    DDS_LOG (DDS_LC_WHC, "whc_default_insert(%p max_drop_seq %"PRId64" seq %"PRId64" plist %p serdata %p:%"PRIx32")\n",
 | 
			
		||||
             (void *)whc, max_drop_seq, seq, (void*)plist, (void*)serdata, serdata->hash);
 | 
			
		||||
    DDS_LOG (DDS_LC_WHC, "  whc: [%"PRId64",%"PRId64"] max_drop_seq %"PRId64" h %"PRIu32" tl %"PRIu32"\n",
 | 
			
		||||
             whcst.min_seq, whcst.max_seq, whc->max_drop_seq, whc->hdepth, whc->tldepth);
 | 
			
		||||
    TRACE ("whc_default_insert(%p max_drop_seq %"PRId64" seq %"PRId64" plist %p serdata %p:%"PRIx32")\n",
 | 
			
		||||
           (void *) whc, max_drop_seq, seq, (void *) plist, (void *) serdata, serdata->hash);
 | 
			
		||||
    TRACE ("  whc: [%"PRId64",%"PRId64"] max_drop_seq %"PRId64" h %"PRIu32" tl %"PRIu32"\n",
 | 
			
		||||
           whcst.min_seq, whcst.max_seq, whc->max_drop_seq, whc->hdepth, whc->tldepth);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  assert (max_drop_seq < MAX_SEQ_NUMBER);
 | 
			
		||||
| 
						 | 
				
			
			@ -1133,12 +1137,12 @@ static int whc_default_insert (struct whc *whc_generic, seqno_t max_drop_seq, se
 | 
			
		|||
  /* Always insert in seq admin */
 | 
			
		||||
  newn = whc_default_insert_seq (whc, max_drop_seq, seq, plist, serdata);
 | 
			
		||||
 | 
			
		||||
  DDS_LOG (DDS_LC_WHC, "  whcn %p:", (void*)newn);
 | 
			
		||||
  TRACE ("  whcn %p:", (void*)newn);
 | 
			
		||||
 | 
			
		||||
  /* Special case of empty data (such as commit messages) can't go into index, and if we're not maintaining an index, we're done, too */
 | 
			
		||||
  if (serdata->kind == SDK_EMPTY || whc->idxdepth == 0)
 | 
			
		||||
  {
 | 
			
		||||
    DDS_LOG (DDS_LC_WHC, " empty or no hist\n");
 | 
			
		||||
    TRACE (" empty or no hist\n");
 | 
			
		||||
    ddsrt_mutex_unlock (&whc->lock);
 | 
			
		||||
    return 0;
 | 
			
		||||
  }
 | 
			
		||||
| 
						 | 
				
			
			@ -1147,15 +1151,15 @@ static int whc_default_insert (struct whc *whc_generic, seqno_t max_drop_seq, se
 | 
			
		|||
  if ((idxn = ddsrt_hh_lookup (whc->idx_hash, &template)) != NULL)
 | 
			
		||||
  {
 | 
			
		||||
    /* Unregisters cause deleting of index entry, non-unregister of adding/overwriting in history */
 | 
			
		||||
    DDS_LOG (DDS_LC_WHC, " idxn %p", (void *)idxn);
 | 
			
		||||
    TRACE (" idxn %p", (void *)idxn);
 | 
			
		||||
    if (serdata->statusinfo & NN_STATUSINFO_UNREGISTER)
 | 
			
		||||
    {
 | 
			
		||||
      DDS_LOG (DDS_LC_WHC, " unreg:delete\n");
 | 
			
		||||
      TRACE (" unreg:delete\n");
 | 
			
		||||
      delete_one_instance_from_idx (whc, max_drop_seq, idxn);
 | 
			
		||||
      if (newn->seq <= max_drop_seq)
 | 
			
		||||
      {
 | 
			
		||||
        struct whc_node *prev_seq = newn->prev_seq;
 | 
			
		||||
        DDS_LOG (DDS_LC_WHC, " unreg:seq <= max_drop_seq: delete newn\n");
 | 
			
		||||
        TRACE (" unreg:seq <= max_drop_seq: delete newn\n");
 | 
			
		||||
        whc_delete_one (whc, newn);
 | 
			
		||||
        whc->maxseq_node = prev_seq;
 | 
			
		||||
      }
 | 
			
		||||
| 
						 | 
				
			
			@ -1167,7 +1171,7 @@ static int whc_default_insert (struct whc *whc_generic, seqno_t max_drop_seq, se
 | 
			
		|||
        idxn->headidx = 0;
 | 
			
		||||
      if ((oldn = idxn->hist[idxn->headidx]) != NULL)
 | 
			
		||||
      {
 | 
			
		||||
        DDS_LOG (DDS_LC_WHC, " overwrite whcn %p", (void *)oldn);
 | 
			
		||||
        TRACE (" overwrite whcn %p", (void *)oldn);
 | 
			
		||||
        oldn->idxnode = NULL;
 | 
			
		||||
      }
 | 
			
		||||
      idxn->hist[idxn->headidx] = newn;
 | 
			
		||||
| 
						 | 
				
			
			@ -1176,7 +1180,7 @@ static int whc_default_insert (struct whc *whc_generic, seqno_t max_drop_seq, se
 | 
			
		|||
 | 
			
		||||
      if (oldn && (whc->hdepth > 0 || oldn->seq <= max_drop_seq))
 | 
			
		||||
      {
 | 
			
		||||
        DDS_LOG (DDS_LC_WHC, " prune whcn %p", (void *)oldn);
 | 
			
		||||
        TRACE (" prune whcn %p", (void *)oldn);
 | 
			
		||||
        assert (oldn != whc->maxseq_node);
 | 
			
		||||
        whc_delete_one (whc, oldn);
 | 
			
		||||
      }
 | 
			
		||||
| 
						 | 
				
			
			@ -1192,22 +1196,22 @@ static int whc_default_insert (struct whc *whc_generic, seqno_t max_drop_seq, se
 | 
			
		|||
          pos -= whc->idxdepth;
 | 
			
		||||
        if ((oldn = idxn->hist[pos]) != NULL)
 | 
			
		||||
        {
 | 
			
		||||
          DDS_LOG (DDS_LC_WHC, " prune tl whcn %p", (void *)oldn);
 | 
			
		||||
          TRACE (" prune tl whcn %p", (void *)oldn);
 | 
			
		||||
          assert (oldn != whc->maxseq_node);
 | 
			
		||||
          whc_delete_one (whc, oldn);
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      DDS_LOG (DDS_LC_WHC, "\n");
 | 
			
		||||
      TRACE ("\n");
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  else
 | 
			
		||||
  {
 | 
			
		||||
    DDS_LOG (DDS_LC_WHC, " newkey");
 | 
			
		||||
    TRACE (" newkey");
 | 
			
		||||
    /* Ignore unregisters, but insert everything else */
 | 
			
		||||
    if (!(serdata->statusinfo & NN_STATUSINFO_UNREGISTER))
 | 
			
		||||
    {
 | 
			
		||||
      idxn = ddsrt_malloc (sizeof (*idxn) + whc->idxdepth * sizeof (idxn->hist[0]));
 | 
			
		||||
      DDS_LOG (DDS_LC_WHC, " idxn %p", (void *)idxn);
 | 
			
		||||
      TRACE (" idxn %p", (void *)idxn);
 | 
			
		||||
      ddsi_tkmap_instance_ref (tk);
 | 
			
		||||
      idxn->iid = tk->m_iid;
 | 
			
		||||
      idxn->tk = tk;
 | 
			
		||||
| 
						 | 
				
			
			@ -1223,16 +1227,16 @@ static int whc_default_insert (struct whc *whc_generic, seqno_t max_drop_seq, se
 | 
			
		|||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
      DDS_LOG (DDS_LC_WHC, " unreg:skip");
 | 
			
		||||
      TRACE (" unreg:skip");
 | 
			
		||||
      if (newn->seq <= max_drop_seq)
 | 
			
		||||
      {
 | 
			
		||||
        struct whc_node *prev_seq = newn->prev_seq;
 | 
			
		||||
        DDS_LOG (DDS_LC_WHC, " unreg:seq <= max_drop_seq: delete newn\n");
 | 
			
		||||
        TRACE (" unreg:seq <= max_drop_seq: delete newn\n");
 | 
			
		||||
        whc_delete_one (whc, newn);
 | 
			
		||||
        whc->maxseq_node = prev_seq;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    DDS_LOG (DDS_LC_WHC, "\n");
 | 
			
		||||
    TRACE ("\n");
 | 
			
		||||
  }
 | 
			
		||||
  ddsrt_mutex_unlock (&whc->lock);
 | 
			
		||||
  return 0;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -82,7 +82,6 @@ static dds_return_t try_store (struct rhc *rhc, const struct proxy_writer_info *
 | 
			
		|||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
      DDS_ERROR ("The writer could not deliver data on time, probably due to a local reader resources being full\n");
 | 
			
		||||
      return DDS_RETCODE_TIMEOUT;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
| 
						 | 
				
			
			@ -102,7 +101,7 @@ static dds_return_t deliver_locally (struct writer *wr, struct ddsi_serdata *pay
 | 
			
		|||
      struct proxy_writer_info pwr_info;
 | 
			
		||||
      make_proxy_writer_info (&pwr_info, &wr->e, wr->xqos);
 | 
			
		||||
      for (uint32_t i = 0; rdary[i]; i++) {
 | 
			
		||||
        DDS_TRACE ("reader "PGUIDFMT"\n", PGUID (rdary[i]->e.guid));
 | 
			
		||||
        DDS_CTRACE (&wr->e.gv->logconfig, "reader "PGUIDFMT"\n", PGUID (rdary[i]->e.guid));
 | 
			
		||||
        if ((ret = try_store (rdary[i]->rhc, &pwr_info, payload, tk, &max_block_ms)) != DDS_RETCODE_OK)
 | 
			
		||||
          break;
 | 
			
		||||
      }
 | 
			
		||||
| 
						 | 
				
			
			@ -132,7 +131,7 @@ static dds_return_t deliver_locally (struct writer *wr, struct ddsi_serdata *pay
 | 
			
		|||
      struct reader *rd;
 | 
			
		||||
      if ((rd = ephash_lookup_reader_guid (gh, &m->rd_guid)) != NULL)
 | 
			
		||||
      {
 | 
			
		||||
        DDS_TRACE ("reader-via-guid "PGUIDFMT"\n", PGUID (rd->e.guid));
 | 
			
		||||
        DDS_CTRACE (&wr->e.gv->logconfig, "reader-via-guid "PGUIDFMT"\n", PGUID (rd->e.guid));
 | 
			
		||||
        /* Copied the return value ignore from DDSI deliver_user_data () function. */
 | 
			
		||||
        if ((ret = try_store (rd->rhc, &pwr_info, payload, tk, &max_block_ms)) != DDS_RETCODE_OK)
 | 
			
		||||
          break;
 | 
			
		||||
| 
						 | 
				
			
			@ -140,6 +139,11 @@ static dds_return_t deliver_locally (struct writer *wr, struct ddsi_serdata *pay
 | 
			
		|||
    }
 | 
			
		||||
    ddsrt_mutex_unlock (&wr->e.lock);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (ret == DDS_RETCODE_TIMEOUT)
 | 
			
		||||
  {
 | 
			
		||||
    DDS_CERROR (&wr->e.gv->logconfig, "The writer could not deliver data on time, probably due to a local reader resources being full\n");
 | 
			
		||||
  }
 | 
			
		||||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -288,7 +288,7 @@ dds_entity_t dds_create_writer (dds_entity_t participant_or_publisher, dds_entit
 | 
			
		|||
    nn_xqos_mergein_missing (wqos, tp->m_entity.m_qos, ~(uint64_t)0);
 | 
			
		||||
  nn_xqos_mergein_missing (wqos, &pub->m_entity.m_domain->gv.default_xqos_wr, ~(uint64_t)0);
 | 
			
		||||
 | 
			
		||||
  if ((rc = nn_xqos_valid (wqos)) < 0)
 | 
			
		||||
  if ((rc = nn_xqos_valid (&pub->m_entity.m_domain->gv.logconfig, wqos)) < 0)
 | 
			
		||||
  {
 | 
			
		||||
    dds_delete_qos(wqos);
 | 
			
		||||
    goto err_bad_qos;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -336,7 +336,7 @@ CU_Test(ddsc_entity, get_entities, .init = create_entity, .fini = delete_entity)
 | 
			
		|||
CU_Test(ddsc_entity, get_domainid, .init = create_entity, .fini = delete_entity)
 | 
			
		||||
{
 | 
			
		||||
    dds_return_t status;
 | 
			
		||||
    dds_domainid_t id = -1;
 | 
			
		||||
    dds_domainid_t id = DDS_DOMAIN_DEFAULT;
 | 
			
		||||
 | 
			
		||||
    /* Check getting ID with bad parameters. */
 | 
			
		||||
    status = dds_get_domainid (0, NULL);
 | 
			
		||||
| 
						 | 
				
			
			@ -349,7 +349,7 @@ CU_Test(ddsc_entity, get_domainid, .init = create_entity, .fini = delete_entity)
 | 
			
		|||
    /* Get and check the domain id. */
 | 
			
		||||
    status = dds_get_domainid (entity, &id);
 | 
			
		||||
    CU_ASSERT_EQUAL_FATAL(status, DDS_RETCODE_OK);
 | 
			
		||||
    CU_ASSERT_FATAL(id != -1);
 | 
			
		||||
    CU_ASSERT_FATAL(id != DDS_DOMAIN_DEFAULT);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
CU_Test(ddsc_entity, delete, .init = create_entity)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -42,17 +42,13 @@ CU_Test(ddsc_participant, create_and_delete) {
 | 
			
		|||
/* Test for creating participant with no configuration file  */
 | 
			
		||||
CU_Test(ddsc_participant, create_with_no_conf_no_env)
 | 
			
		||||
{
 | 
			
		||||
  dds_entity_t participant, participant2, participant3;
 | 
			
		||||
  dds_entity_t participant2, participant3;
 | 
			
		||||
  dds_return_t status;
 | 
			
		||||
  dds_domainid_t domain_id;
 | 
			
		||||
  dds_domainid_t valid_domain=3;
 | 
			
		||||
 | 
			
		||||
  ddsrt_unsetenv(DDS_PROJECT_NAME_NOSPACE_CAPS"_URI");
 | 
			
		||||
 | 
			
		||||
  //invalid domain
 | 
			
		||||
  participant = dds_create_participant (-2, NULL, NULL);
 | 
			
		||||
  CU_ASSERT_FATAL(participant < 0);
 | 
			
		||||
 | 
			
		||||
  //valid specific domain value
 | 
			
		||||
  participant2 = dds_create_participant (valid_domain, NULL, NULL);
 | 
			
		||||
  CU_ASSERT_FATAL(participant2 > 0);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -30,9 +30,9 @@ struct ddsi_ssl_plugins
 | 
			
		|||
  void (*bio_vfree) (BIO *bio);
 | 
			
		||||
  ssize_t (*read) (SSL *ssl, void *buf, size_t len, dds_return_t *err);
 | 
			
		||||
  ssize_t (*write) (SSL *ssl, const void *msg, size_t len, dds_return_t *err);
 | 
			
		||||
  SSL * (*connect) (ddsrt_socket_t sock);
 | 
			
		||||
  SSL * (*connect) (const struct q_globals *gv, ddsrt_socket_t sock);
 | 
			
		||||
  BIO * (*listen) (ddsrt_socket_t sock);
 | 
			
		||||
  SSL * (*accept) (BIO *bio, ddsrt_socket_t *sock);
 | 
			
		||||
  SSL * (*accept) (const struct q_globals *gv, BIO *bio, ddsrt_socket_t *sock);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#if defined (__cplusplus)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -17,10 +17,12 @@ extern "C" {
 | 
			
		|||
#endif
 | 
			
		||||
 | 
			
		||||
struct ddsi_threadmon;
 | 
			
		||||
struct config_thread_properties_listelem;
 | 
			
		||||
struct q_globals;
 | 
			
		||||
 | 
			
		||||
struct ddsi_threadmon *ddsi_threadmon_new (int64_t liveliness_monitoring_interval, bool noprogress_log_stacktraces);
 | 
			
		||||
dds_return_t ddsi_threadmon_start (struct ddsi_threadmon *sl, const char *name, const struct config_thread_properties_listelem *tprops);
 | 
			
		||||
dds_return_t ddsi_threadmon_start (struct ddsi_threadmon *sl, const char *name);
 | 
			
		||||
void ddsi_threadmon_register_domain (struct ddsi_threadmon *sl, const struct q_globals *gv);
 | 
			
		||||
void ddsi_threadmon_unregister_domain (struct ddsi_threadmon *sl, const struct q_globals *gv);
 | 
			
		||||
void ddsi_threadmon_stop (struct ddsi_threadmon *sl);
 | 
			
		||||
void ddsi_threadmon_free (struct ddsi_threadmon *sl);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -35,7 +35,7 @@ DDS_EXPORT struct ddsi_tkmap *ddsi_tkmap_new (struct q_globals *gv);
 | 
			
		|||
DDS_EXPORT void ddsi_tkmap_free (struct ddsi_tkmap *tkmap);
 | 
			
		||||
DDS_EXPORT void ddsi_tkmap_instance_ref (struct ddsi_tkmap_instance *tk);
 | 
			
		||||
DDS_EXPORT uint64_t ddsi_tkmap_lookup (struct ddsi_tkmap *tkmap, const struct ddsi_serdata *serdata);
 | 
			
		||||
DDS_EXPORT struct ddsi_tkmap_instance * ddsi_tkmap_find(struct ddsi_tkmap *map, struct ddsi_serdata *sd, const bool rd, const bool create);
 | 
			
		||||
DDS_EXPORT struct ddsi_tkmap_instance * ddsi_tkmap_find(struct ddsi_tkmap *map, struct ddsi_serdata *sd, const bool create);
 | 
			
		||||
DDS_EXPORT struct ddsi_tkmap_instance * ddsi_tkmap_find_by_id (struct ddsi_tkmap *map, uint64_t iid);
 | 
			
		||||
DDS_EXPORT struct ddsi_tkmap_instance * ddsi_tkmap_lookup_instance_ref (struct ddsi_tkmap *map, struct ddsi_serdata * sd);
 | 
			
		||||
DDS_EXPORT void ddsi_tkmap_instance_unref (struct ddsi_tkmap *map, struct ddsi_tkmap_instance *tk);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -244,10 +244,10 @@ struct config
 | 
			
		|||
  enum boolean_default compat_tcp_enable;
 | 
			
		||||
  int dontRoute;
 | 
			
		||||
  int enableMulticastLoopback;
 | 
			
		||||
  struct config_maybe_int32 domainId;
 | 
			
		||||
  struct config_maybe_uint32 domainId;
 | 
			
		||||
  int participantIndex;
 | 
			
		||||
  int maxAutoParticipantIndex;
 | 
			
		||||
  int port_base;
 | 
			
		||||
  uint32_t port_base;
 | 
			
		||||
  char *spdpMulticastAddressString;
 | 
			
		||||
  char *defaultMulticastAddressString;
 | 
			
		||||
  char *assumeMulticastCapable;
 | 
			
		||||
| 
						 | 
				
			
			@ -373,12 +373,12 @@ struct config
 | 
			
		|||
  enum many_sockets_mode many_sockets_mode;
 | 
			
		||||
  int assume_rti_has_pmd_endpoints;
 | 
			
		||||
 | 
			
		||||
  int port_dg;
 | 
			
		||||
  int port_pg;
 | 
			
		||||
  int port_d0;
 | 
			
		||||
  int port_d1;
 | 
			
		||||
  int port_d2;
 | 
			
		||||
  int port_d3;
 | 
			
		||||
  uint32_t port_dg;
 | 
			
		||||
  uint32_t port_pg;
 | 
			
		||||
  uint32_t port_d0;
 | 
			
		||||
  uint32_t port_d1;
 | 
			
		||||
  uint32_t port_d2;
 | 
			
		||||
  uint32_t port_d3;
 | 
			
		||||
 | 
			
		||||
  int monitor_port;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -393,8 +393,8 @@ struct config
 | 
			
		|||
 | 
			
		||||
struct cfgst;
 | 
			
		||||
 | 
			
		||||
struct cfgst *config_init (const char *configfile, struct config *cfg);
 | 
			
		||||
void config_print_cfgst (struct cfgst *cfgst);
 | 
			
		||||
struct cfgst *config_init (const char *configfile, struct config *cfg, uint32_t domid);
 | 
			
		||||
void config_print_cfgst (struct cfgst *cfgst, const struct ddsrt_log_cfg *logcfg);
 | 
			
		||||
void config_free_source_info (struct cfgst *cfgst);
 | 
			
		||||
void config_fini (struct cfgst *cfgst);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -91,6 +91,7 @@ struct q_globals {
 | 
			
		|||
  volatile int deaf;
 | 
			
		||||
  volatile int mute;
 | 
			
		||||
 | 
			
		||||
  struct ddsrt_log_cfg logconfig;
 | 
			
		||||
  struct config config;
 | 
			
		||||
 | 
			
		||||
  struct ddsi_tkmap * m_tkmap;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -33,7 +33,7 @@ void nn_lat_estim_init (struct nn_lat_estim *le);
 | 
			
		|||
void nn_lat_estim_fini (struct nn_lat_estim *le);
 | 
			
		||||
void nn_lat_estim_update (struct nn_lat_estim *le, int64_t est);
 | 
			
		||||
double nn_lat_estim_current (const struct nn_lat_estim *le);
 | 
			
		||||
int nn_lat_estim_log (uint32_t logcat, const char *tag, const struct nn_lat_estim *le);
 | 
			
		||||
int nn_lat_estim_log (uint32_t logcat, const struct ddsrt_log_cfg *logcfg, const char *tag, const struct nn_lat_estim *le);
 | 
			
		||||
 | 
			
		||||
#if defined (__cplusplus)
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -22,17 +22,36 @@
 | 
			
		|||
extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define GVTRACE(...)        DDS_CTRACE (&gv->logconfig, __VA_ARGS__)
 | 
			
		||||
#define GVLOG(cat, ...)     DDS_CLOG ((cat), &gv->logconfig, __VA_ARGS__)
 | 
			
		||||
#define GVWARNING(...)      DDS_CLOG (DDS_LC_WARNING, &gv->logconfig, __VA_ARGS__)
 | 
			
		||||
#define GVERROR(...)        DDS_CLOG (DDS_LC_ERROR, &gv->logconfig, __VA_ARGS__)
 | 
			
		||||
 | 
			
		||||
#define RSTTRACE(...)       DDS_CTRACE (&rst->gv->logconfig, __VA_ARGS__)
 | 
			
		||||
 | 
			
		||||
#define ETRACE(e_, ...)     DDS_CTRACE (&(e_)->e.gv->logconfig, __VA_ARGS__)
 | 
			
		||||
#define EETRACE(e_, ...)    DDS_CTRACE (&(e_)->gv->logconfig, __VA_ARGS__)
 | 
			
		||||
#define ELOG(cat, e_, ...)  DDS_CLOG ((cat), &(e_)->e.gv->logconfig, __VA_ARGS__)
 | 
			
		||||
#define EELOG(cat, e_, ...) DDS_CLOG ((cat), &(e_)->gv->logconfig, __VA_ARGS__)
 | 
			
		||||
 | 
			
		||||
/* There are quite a few places where discovery-related things are logged, so abbreviate those
 | 
			
		||||
   a bit */
 | 
			
		||||
#define GVLOGDISC(...)      DDS_CLOG (DDS_LC_DISCOVERY, &gv->logconfig, __VA_ARGS__)
 | 
			
		||||
#define ELOGDISC(e_,...)    DDS_CLOG (DDS_LC_DISCOVERY, &(e_)->e.gv->logconfig, __VA_ARGS__)
 | 
			
		||||
#define EELOGDISC(e_, ...)  DDS_CLOG (DDS_LC_DISCOVERY, &(e_)->gv->logconfig, __VA_ARGS__)
 | 
			
		||||
 | 
			
		||||
/* LOG_THREAD_CPUTIME must be considered private. */
 | 
			
		||||
#if DDSRT_HAVE_RUSAGE
 | 
			
		||||
#define LOG_THREAD_CPUTIME(guard)                                        \
 | 
			
		||||
#define LOG_THREAD_CPUTIME(logcfg, guard)                                \
 | 
			
		||||
    do {                                                                 \
 | 
			
		||||
        if (dds_get_log_mask() & DDS_LC_TIMING) {                        \
 | 
			
		||||
        if ((logcfg)->c.mask & DDS_LC_TIMING) {                          \
 | 
			
		||||
            nn_mtime_t tnowlt = now_mt();                                \
 | 
			
		||||
            if (tnowlt.v >= (guard).v) {                                 \
 | 
			
		||||
                ddsrt_rusage_t usage;                                    \
 | 
			
		||||
                if (ddsrt_getrusage(DDSRT_RUSAGE_THREAD, &usage) == 0) { \
 | 
			
		||||
                    DDS_LOG(                                             \
 | 
			
		||||
                    DDS_CLOG(                                            \
 | 
			
		||||
                        DDS_LC_TIMING,                                   \
 | 
			
		||||
                        (logcfg),                                        \
 | 
			
		||||
                        "thread_cputime %d.%09d\n",                      \
 | 
			
		||||
                        (int)(usage.stime / DDS_NSECS_IN_SEC),           \
 | 
			
		||||
                        (int)(usage.stime % DDS_NSECS_IN_SEC));          \
 | 
			
		||||
| 
						 | 
				
			
			@ -42,7 +61,7 @@ extern "C" {
 | 
			
		|||
        }                                                                \
 | 
			
		||||
    } while (0)
 | 
			
		||||
#else
 | 
			
		||||
#define LOG_THREAD_CPUTIME(guard) (void)(guard)
 | 
			
		||||
#define LOG_THREAD_CPUTIME(logcfg, guard) (void)(guard)
 | 
			
		||||
#endif /* DDSRT_HAVE_RUSAGE */
 | 
			
		||||
 | 
			
		||||
#if defined (__cplusplus)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -21,7 +21,7 @@ extern "C" {
 | 
			
		|||
 | 
			
		||||
struct msghdr;
 | 
			
		||||
 | 
			
		||||
FILE * new_pcap_file (const char *name);
 | 
			
		||||
FILE * new_pcap_file (const struct ddsrt_log_cfg *logcfg, const char *name);
 | 
			
		||||
 | 
			
		||||
void write_pcap_received (struct q_globals *gv, nn_wctime_t tstamp, const struct sockaddr_storage *src, const struct sockaddr_storage *dst, unsigned char *buf, size_t sz);
 | 
			
		||||
void write_pcap_sent (struct q_globals *gv, nn_wctime_t tstamp, const struct sockaddr_storage *src,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -175,6 +175,7 @@ typedef struct nn_plist_src {
 | 
			
		|||
  size_t bufsz;
 | 
			
		||||
  bool strict;
 | 
			
		||||
  ddsi_tran_factory_t factory; /* eliminate this */
 | 
			
		||||
  struct ddsrt_log_cfg *logconfig;
 | 
			
		||||
} nn_plist_src_t;
 | 
			
		||||
 | 
			
		||||
void nn_plist_init_tables (void);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -93,6 +93,9 @@ struct nn_rmsg {
 | 
			
		|||
     the real packet. */
 | 
			
		||||
  struct nn_rmsg_chunk *lastchunk;
 | 
			
		||||
 | 
			
		||||
  /* whether to log */
 | 
			
		||||
  bool trace;
 | 
			
		||||
 | 
			
		||||
  struct nn_rmsg_chunk chunk;
 | 
			
		||||
};
 | 
			
		||||
#define NN_RMSG_PAYLOAD(m) ((unsigned char *) (&(m)->chunk + 1))
 | 
			
		||||
| 
						 | 
				
			
			@ -195,7 +198,7 @@ typedef int32_t nn_reorder_result_t;
 | 
			
		|||
 | 
			
		||||
typedef void (*nn_dqueue_callback_t) (void *arg);
 | 
			
		||||
 | 
			
		||||
struct nn_rbufpool *nn_rbufpool_new (uint32_t rbuf_size, uint32_t max_rmsg_size);
 | 
			
		||||
struct nn_rbufpool *nn_rbufpool_new (const struct ddsrt_log_cfg *logcfg, uint32_t rbuf_size, uint32_t max_rmsg_size);
 | 
			
		||||
void nn_rbufpool_setowner (struct nn_rbufpool *rbp, ddsrt_thread_t tid);
 | 
			
		||||
void nn_rbufpool_free (struct nn_rbufpool *rbp);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -210,13 +213,13 @@ struct nn_rdata *nn_rdata_newgap (struct nn_rmsg *rmsg);
 | 
			
		|||
void nn_fragchain_adjust_refcount (struct nn_rdata *frag, int adjust);
 | 
			
		||||
void nn_fragchain_unref (struct nn_rdata *frag);
 | 
			
		||||
 | 
			
		||||
struct nn_defrag *nn_defrag_new (enum nn_defrag_drop_mode drop_mode, uint32_t max_samples);
 | 
			
		||||
struct nn_defrag *nn_defrag_new (const struct ddsrt_log_cfg *logcfg, enum nn_defrag_drop_mode drop_mode, uint32_t max_samples);
 | 
			
		||||
void nn_defrag_free (struct nn_defrag *defrag);
 | 
			
		||||
struct nn_rsample *nn_defrag_rsample (struct nn_defrag *defrag, struct nn_rdata *rdata, const struct nn_rsample_info *sampleinfo);
 | 
			
		||||
void nn_defrag_notegap (struct nn_defrag *defrag, seqno_t min, seqno_t maxp1);
 | 
			
		||||
int nn_defrag_nackmap (struct nn_defrag *defrag, seqno_t seq, uint32_t maxfragnum, struct nn_fragment_number_set_header *map, uint32_t *mapbits, uint32_t maxsz);
 | 
			
		||||
 | 
			
		||||
struct nn_reorder *nn_reorder_new (enum nn_reorder_mode mode, uint32_t max_samples, bool late_ack_mode);
 | 
			
		||||
struct nn_reorder *nn_reorder_new (const struct ddsrt_log_cfg *logcfg, enum nn_reorder_mode mode, uint32_t max_samples, bool late_ack_mode);
 | 
			
		||||
void nn_reorder_free (struct nn_reorder *r);
 | 
			
		||||
struct nn_rsample *nn_reorder_rsample_dup_first (struct nn_rmsg *rmsg, struct nn_rsample *rsampleiv);
 | 
			
		||||
struct nn_rdata *nn_rsample_fragchain (struct nn_rsample *rsample);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -56,7 +56,7 @@ enum thread_state {
 | 
			
		|||
 | 
			
		||||
struct q_globals;
 | 
			
		||||
struct config;
 | 
			
		||||
struct logbuf;
 | 
			
		||||
struct ddsrt_log_cfg;
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * vtime indicates progress for the garbage collector and the liveliness monitoring.
 | 
			
		||||
| 
						 | 
				
			
			@ -109,7 +109,7 @@ DDS_EXPORT dds_return_t create_thread_with_properties (struct thread_state1 **ts
 | 
			
		|||
DDS_EXPORT dds_return_t create_thread (struct thread_state1 **ts, const struct q_globals *gv, const char *name, uint32_t (*f) (void *arg), void *arg);
 | 
			
		||||
DDS_EXPORT struct thread_state1 *lookup_thread_state_real (void);
 | 
			
		||||
DDS_EXPORT dds_return_t join_thread (struct thread_state1 *ts1);
 | 
			
		||||
DDS_EXPORT void log_stack_traces (void);
 | 
			
		||||
DDS_EXPORT void log_stack_traces (const struct ddsrt_log_cfg *logcfg, const struct q_globals *gv);
 | 
			
		||||
DDS_EXPORT void reset_thread_state (struct thread_state1 *ts1);
 | 
			
		||||
DDS_EXPORT int thread_exists (const char *name);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -278,11 +278,11 @@ DDS_EXPORT void nn_xqos_copy (dds_qos_t *dst, const dds_qos_t *src);
 | 
			
		|||
DDS_EXPORT void nn_xqos_unalias (dds_qos_t *xqos);
 | 
			
		||||
DDS_EXPORT void nn_xqos_fini (dds_qos_t *xqos);
 | 
			
		||||
DDS_EXPORT void nn_xqos_fini_mask (dds_qos_t *xqos, uint64_t mask);
 | 
			
		||||
DDS_EXPORT dds_return_t nn_xqos_valid (const dds_qos_t *xqos);
 | 
			
		||||
DDS_EXPORT dds_return_t nn_xqos_valid (const struct ddsrt_log_cfg *logcfg, const dds_qos_t *xqos);
 | 
			
		||||
DDS_EXPORT void nn_xqos_mergein_missing (dds_qos_t *a, const dds_qos_t *b, uint64_t mask);
 | 
			
		||||
DDS_EXPORT uint64_t nn_xqos_delta (const dds_qos_t *a, const dds_qos_t *b, uint64_t mask);
 | 
			
		||||
DDS_EXPORT void nn_xqos_addtomsg (struct nn_xmsg *m, const dds_qos_t *xqos, uint64_t wanted);
 | 
			
		||||
DDS_EXPORT void nn_log_xqos (uint32_t cat, const dds_qos_t *xqos);
 | 
			
		||||
DDS_EXPORT void nn_log_xqos (uint32_t cat, const struct ddsrt_log_cfg *logcfg, const dds_qos_t *xqos);
 | 
			
		||||
DDS_EXPORT dds_qos_t *nn_xqos_dup (const dds_qos_t *src);
 | 
			
		||||
 | 
			
		||||
#if defined (__cplusplus)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -22,7 +22,7 @@ extern "C" {
 | 
			
		|||
#define ASSERT_WRLOCK_HELD(x) ((void) 0)
 | 
			
		||||
#define ASSERT_MUTEX_HELD(x) ((void) 0)
 | 
			
		||||
 | 
			
		||||
void log_stacktrace (const char *name, ddsrt_thread_t tid);
 | 
			
		||||
void log_stacktrace (const struct ddsrt_log_cfg *logcfg, const char *name, ddsrt_thread_t tid);
 | 
			
		||||
 | 
			
		||||
#if defined (__cplusplus)
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -156,13 +156,13 @@ static int joinleave_mcgroup (ddsi_tran_conn_t conn, int join, const nn_locator_
 | 
			
		|||
{
 | 
			
		||||
  char buf[256];
 | 
			
		||||
  int err;
 | 
			
		||||
  DDS_TRACE("%s\n", make_joinleave_msg (buf, sizeof(buf), conn, join, srcloc, mcloc, interf, 0));
 | 
			
		||||
  DDS_CTRACE(&conn->m_base.gv->logconfig, "%s\n", make_joinleave_msg (buf, sizeof(buf), conn, join, srcloc, mcloc, interf, 0));
 | 
			
		||||
  if (join)
 | 
			
		||||
    err = ddsi_conn_join_mc(conn, srcloc, mcloc, interf);
 | 
			
		||||
  else
 | 
			
		||||
    err = ddsi_conn_leave_mc(conn, srcloc, mcloc, interf);
 | 
			
		||||
  if (err)
 | 
			
		||||
    DDS_WARNING("%s\n", make_joinleave_msg (buf, sizeof(buf), conn, join, srcloc, mcloc, interf, err));
 | 
			
		||||
    DDS_CWARNING(&conn->m_base.gv->logconfig, "%s\n", make_joinleave_msg (buf, sizeof(buf), conn, join, srcloc, mcloc, interf, err));
 | 
			
		||||
  return err ? -1 : 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -213,7 +213,7 @@ static int joinleave_mcgroups (const struct q_globals *gv, ddsi_tran_conn_t conn
 | 
			
		|||
      if (fails > 0)
 | 
			
		||||
      {
 | 
			
		||||
        if (oks > 0)
 | 
			
		||||
          DDS_TRACE("multicast join failed for some but not all interfaces, proceeding\n");
 | 
			
		||||
          GVTRACE("multicast join failed for some but not all interfaces, proceeding\n");
 | 
			
		||||
        else
 | 
			
		||||
          return -2;
 | 
			
		||||
      }
 | 
			
		||||
| 
						 | 
				
			
			@ -231,7 +231,7 @@ int ddsi_join_mc (const struct q_globals *gv, struct nn_group_membership *mship,
 | 
			
		|||
  if (!reg_group_membership (mship, conn, srcloc, mcloc))
 | 
			
		||||
  {
 | 
			
		||||
    char buf[256];
 | 
			
		||||
    DDS_TRACE("%s: already joined\n", make_joinleave_msg (buf, sizeof(buf), conn, 1, srcloc, mcloc, NULL, 0));
 | 
			
		||||
    GVTRACE("%s: already joined\n", make_joinleave_msg (buf, sizeof(buf), conn, 1, srcloc, mcloc, NULL, 0));
 | 
			
		||||
    ret = 0;
 | 
			
		||||
  }
 | 
			
		||||
  else
 | 
			
		||||
| 
						 | 
				
			
			@ -249,7 +249,7 @@ int ddsi_leave_mc (const struct q_globals *gv, struct nn_group_membership *mship
 | 
			
		|||
  if (!unreg_group_membership (mship, conn, srcloc, mcloc))
 | 
			
		||||
  {
 | 
			
		||||
    char buf[256];
 | 
			
		||||
    DDS_TRACE("%s: not leaving yet\n", make_joinleave_msg (buf, sizeof(buf), conn, 0, srcloc, mcloc, NULL, 0));
 | 
			
		||||
    GVTRACE("%s: not leaving yet\n", make_joinleave_msg (buf, sizeof(buf), conn, 0, srcloc, mcloc, NULL, 0));
 | 
			
		||||
    ret = 0;
 | 
			
		||||
  }
 | 
			
		||||
  else
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -97,14 +97,14 @@ static ssize_t ddsi_raweth_conn_read (ddsi_tran_conn_t conn, unsigned char * buf
 | 
			
		|||
      snprintf(addrbuf, sizeof(addrbuf), "[%02x:%02x:%02x:%02x:%02x:%02x]:%u",
 | 
			
		||||
               src.sll_addr[0], src.sll_addr[1], src.sll_addr[2],
 | 
			
		||||
               src.sll_addr[3], src.sll_addr[4], src.sll_addr[5], ntohs(src.sll_protocol));
 | 
			
		||||
      DDS_WARNING("%s => %d truncated to %d\n", addrbuf, (int)ret, (int)len);
 | 
			
		||||
      DDS_CWARNING(&conn->m_base.gv->logconfig, "%s => %d truncated to %d\n", addrbuf, (int)ret, (int)len);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  else if (rc != DDS_RETCODE_OK &&
 | 
			
		||||
           rc != DDS_RETCODE_BAD_PARAMETER &&
 | 
			
		||||
           rc != DDS_RETCODE_NO_CONNECTION)
 | 
			
		||||
  {
 | 
			
		||||
    DDS_ERROR("UDP recvmsg sock %d: ret %d retcode %d\n", (int) ((ddsi_raweth_conn_t) conn)->m_sock, (int) ret, rc);
 | 
			
		||||
    DDS_CERROR(&conn->m_base.gv->logconfig, "UDP recvmsg sock %d: ret %d retcode %d\n", (int) ((ddsi_raweth_conn_t) conn)->m_sock, (int) ret, rc);
 | 
			
		||||
  }
 | 
			
		||||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -144,7 +144,7 @@ static ssize_t ddsi_raweth_conn_write (ddsi_tran_conn_t conn, const nn_locator_t
 | 
			
		|||
      rc != DDS_RETCODE_NOT_ALLOWED &&
 | 
			
		||||
      rc != DDS_RETCODE_NO_CONNECTION)
 | 
			
		||||
  {
 | 
			
		||||
    DDS_ERROR("ddsi_raweth_conn_write failed with retcode %d", rc);
 | 
			
		||||
    DDS_CERROR(&conn->m_base.gv->logconfig, "ddsi_raweth_conn_write failed with retcode %d", rc);
 | 
			
		||||
  }
 | 
			
		||||
  return (rc == DDS_RETCODE_OK ? ret : -1);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -187,14 +187,14 @@ static ddsi_tran_conn_t ddsi_raweth_create_conn (ddsi_tran_factory_t fact, uint3
 | 
			
		|||
 | 
			
		||||
  if (port == 0 || port > 65535)
 | 
			
		||||
  {
 | 
			
		||||
    DDS_ERROR("ddsi_raweth_create_conn %s port %u - using port number as ethernet type, %u won't do\n", mcast ? "multicast" : "unicast", port, port);
 | 
			
		||||
    DDS_CERROR (&fact->gv->logconfig, "ddsi_raweth_create_conn %s port %u - using port number as ethernet type, %u won't do\n", mcast ? "multicast" : "unicast", port, port);
 | 
			
		||||
    return NULL;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  rc = ddsrt_socket(&sock, PF_PACKET, SOCK_DGRAM, htons((uint16_t)port));
 | 
			
		||||
  if (rc != DDS_RETCODE_OK)
 | 
			
		||||
  {
 | 
			
		||||
    DDS_ERROR("ddsi_raweth_create_conn %s port %u failed ... retcode = %d\n", mcast ? "multicast" : "unicast", port, rc);
 | 
			
		||||
    DDS_CERROR (&fact->gv->logconfig, "ddsi_raweth_create_conn %s port %u failed ... retcode = %d\n", mcast ? "multicast" : "unicast", port, rc);
 | 
			
		||||
    return NULL;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -207,7 +207,7 @@ static ddsi_tran_conn_t ddsi_raweth_create_conn (ddsi_tran_factory_t fact, uint3
 | 
			
		|||
  if (rc != DDS_RETCODE_OK)
 | 
			
		||||
  {
 | 
			
		||||
    ddsrt_close(sock);
 | 
			
		||||
    DDS_ERROR("ddsi_raweth_create_conn %s bind port %u failed ... retcode = %d\n", mcast ? "multicast" : "unicast", port, rc);
 | 
			
		||||
    DDS_CERROR (&fact->gv->logconfig, "ddsi_raweth_create_conn %s bind port %u failed ... retcode = %d\n", mcast ? "multicast" : "unicast", port, rc);
 | 
			
		||||
    return NULL;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -225,7 +225,7 @@ static ddsi_tran_conn_t ddsi_raweth_create_conn (ddsi_tran_factory_t fact, uint3
 | 
			
		|||
  uc->m_base.m_write_fn = ddsi_raweth_conn_write;
 | 
			
		||||
  uc->m_base.m_disable_multiplexing_fn = 0;
 | 
			
		||||
 | 
			
		||||
  DDS_TRACE("ddsi_raweth_create_conn %s socket %d port %u\n", mcast ? "multicast" : "unicast", uc->m_sock, uc->m_base.m_base.m_port);
 | 
			
		||||
  DDS_CTRACE (&fact->gv->logconfig, "ddsi_raweth_create_conn %s socket %d port %u\n", mcast ? "multicast" : "unicast", uc->m_sock, uc->m_base.m_base.m_port);
 | 
			
		||||
  return uc ? &uc->m_base : NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -277,13 +277,11 @@ static int ddsi_raweth_leave_mc (ddsi_tran_conn_t conn, const nn_locator_t *srcl
 | 
			
		|||
static void ddsi_raweth_release_conn (ddsi_tran_conn_t conn)
 | 
			
		||||
{
 | 
			
		||||
  ddsi_raweth_conn_t uc = (ddsi_raweth_conn_t) conn;
 | 
			
		||||
  DDS_TRACE
 | 
			
		||||
  (
 | 
			
		||||
    "ddsi_raweth_release_conn %s socket %d port %d\n",
 | 
			
		||||
    conn->m_base.m_multicast ? "multicast" : "unicast",
 | 
			
		||||
    uc->m_sock,
 | 
			
		||||
    uc->m_base.m_base.m_port
 | 
			
		||||
  );
 | 
			
		||||
  DDS_CTRACE (&conn->m_base.gv->logconfig,
 | 
			
		||||
              "ddsi_raweth_release_conn %s socket %d port %d\n",
 | 
			
		||||
              conn->m_base.m_multicast ? "multicast" : "unicast",
 | 
			
		||||
              uc->m_sock,
 | 
			
		||||
              uc->m_base.m_base.m_port);
 | 
			
		||||
  ddsrt_close (uc->m_sock);
 | 
			
		||||
  ddsrt_free (conn);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -341,8 +339,8 @@ static enum ddsi_locator_from_string_result ddsi_raweth_address_from_string (dds
 | 
			
		|||
 | 
			
		||||
static void ddsi_raweth_deinit(ddsi_tran_factory_t fact)
 | 
			
		||||
{
 | 
			
		||||
  DDS_CLOG (DDS_LC_CONFIG, &fact->gv->logconfig, "raweth de-initialized\n");
 | 
			
		||||
  ddsrt_free (fact);
 | 
			
		||||
  DDS_LOG(DDS_LC_CONFIG, "raweth de-initialized\n");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int ddsi_raweth_enumerate_interfaces (ddsi_tran_factory_t fact, enum transport_selector transport_selector, ddsrt_ifaddrs_t **ifs)
 | 
			
		||||
| 
						 | 
				
			
			@ -375,7 +373,7 @@ int ddsi_raweth_init (struct q_globals *gv)
 | 
			
		|||
  fact->m_locator_to_string_fn = ddsi_raweth_to_string;
 | 
			
		||||
  fact->m_enumerate_interfaces_fn = ddsi_raweth_enumerate_interfaces;
 | 
			
		||||
  ddsi_factory_add (gv, fact);
 | 
			
		||||
  DDS_LOG(DDS_LC_CONFIG, "raweth initialized\n");
 | 
			
		||||
  GVLOG (DDS_LC_CONFIG, "raweth initialized\n");
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -73,7 +73,6 @@ static void serdata_free_wrap (void *elem)
 | 
			
		|||
 | 
			
		||||
void ddsi_serdatapool_free (struct serdatapool * pool)
 | 
			
		||||
{
 | 
			
		||||
  DDS_TRACE("ddsi_serdatapool_free(%p)\n", (void *) pool);
 | 
			
		||||
  nn_freelist_fini (&pool->freelist, serdata_free_wrap);
 | 
			
		||||
  ddsrt_free (pool);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -38,11 +38,11 @@ static SSL *ddsi_ssl_new (void)
 | 
			
		|||
  return SSL_new (ddsi_ssl_ctx);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void ddsi_ssl_error (SSL *ssl, const char *str, int err)
 | 
			
		||||
static void ddsi_ssl_error (const struct q_globals *gv, SSL *ssl, const char *str, int err)
 | 
			
		||||
{
 | 
			
		||||
  char buff[128];
 | 
			
		||||
  ERR_error_string ((unsigned) SSL_get_error (ssl, err), buff);
 | 
			
		||||
  DDS_ERROR ("tcp/ssl %s %s %d\n", str, buff, err);
 | 
			
		||||
  GVERROR ("tcp/ssl %s %s %d\n", str, buff, err);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int ddsi_ssl_verify (int ok, X509_STORE_CTX *store)
 | 
			
		||||
| 
						 | 
				
			
			@ -196,7 +196,7 @@ static SSL_CTX *ddsi_ssl_ctx_init (struct q_globals *gv)
 | 
			
		|||
  /* Load certificates */
 | 
			
		||||
  if (! SSL_CTX_use_certificate_file (ctx, gv->config.ssl_keystore, SSL_FILETYPE_PEM))
 | 
			
		||||
  {
 | 
			
		||||
    DDS_LOG (DDS_LC_ERROR | DDS_LC_CONFIG, "tcp/ssl failed to load certificate from file: %s\n", gv->config.ssl_keystore);
 | 
			
		||||
    GVLOG (DDS_LC_ERROR | DDS_LC_CONFIG, "tcp/ssl failed to load certificate from file: %s\n", gv->config.ssl_keystore);
 | 
			
		||||
    goto fail;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -207,21 +207,21 @@ static SSL_CTX *ddsi_ssl_ctx_init (struct q_globals *gv)
 | 
			
		|||
  /* Get private key */
 | 
			
		||||
  if (! SSL_CTX_use_PrivateKey_file (ctx, gv->config.ssl_keystore, SSL_FILETYPE_PEM))
 | 
			
		||||
  {
 | 
			
		||||
    DDS_LOG (DDS_LC_ERROR | DDS_LC_CONFIG, "tcp/ssl failed to load private key from file: %s\n", gv->config.ssl_keystore);
 | 
			
		||||
    GVLOG (DDS_LC_ERROR | DDS_LC_CONFIG, "tcp/ssl failed to load private key from file: %s\n", gv->config.ssl_keystore);
 | 
			
		||||
    goto fail;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /* Load CAs */
 | 
			
		||||
  if (! SSL_CTX_load_verify_locations (ctx, gv->config.ssl_keystore, 0))
 | 
			
		||||
  {
 | 
			
		||||
    DDS_LOG (DDS_LC_ERROR | DDS_LC_CONFIG, "tcp/ssl failed to load CA from file: %s\n", gv->config.ssl_keystore);
 | 
			
		||||
    GVLOG (DDS_LC_ERROR | DDS_LC_CONFIG, "tcp/ssl failed to load CA from file: %s\n", gv->config.ssl_keystore);
 | 
			
		||||
    goto fail;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /* Set ciphers */
 | 
			
		||||
  if (! SSL_CTX_set_cipher_list (ctx, gv->config.ssl_ciphers))
 | 
			
		||||
  {
 | 
			
		||||
    DDS_LOG (DDS_LC_ERROR | DDS_LC_CONFIG, "tcp/ssl failed to set ciphers: %s\n", gv->config.ssl_ciphers);
 | 
			
		||||
    GVLOG (DDS_LC_ERROR | DDS_LC_CONFIG, "tcp/ssl failed to set ciphers: %s\n", gv->config.ssl_ciphers);
 | 
			
		||||
    goto fail;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -230,7 +230,7 @@ static SSL_CTX *ddsi_ssl_ctx_init (struct q_globals *gv)
 | 
			
		|||
  {
 | 
			
		||||
    if (! RAND_load_file (gv->config.ssl_rand_file, 4096))
 | 
			
		||||
    {
 | 
			
		||||
      DDS_LOG (DDS_LC_ERROR | DDS_LC_CONFIG, "tcp/ssl failed to load random seed from file: %s\n", gv->config.ssl_rand_file);
 | 
			
		||||
      GVLOG (DDS_LC_ERROR | DDS_LC_CONFIG, "tcp/ssl failed to load random seed from file: %s\n", gv->config.ssl_rand_file);
 | 
			
		||||
      goto fail;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
| 
						 | 
				
			
			@ -260,17 +260,17 @@ static SSL_CTX *ddsi_ssl_ctx_init (struct q_globals *gv)
 | 
			
		|||
#ifdef SSL_OP_NO_TLSv1_2
 | 
			
		||||
          disallow_TLSv1_2 = SSL_OP_NO_TLSv1_2;
 | 
			
		||||
#else
 | 
			
		||||
          DDS_LOG (DDS_LC_ERROR | DDS_LC_CONFIG, "tcp/ssl: openssl version does not support disabling TLSv1.2 as required by gv->config\n");
 | 
			
		||||
          GVLOG (DDS_LC_ERROR | DDS_LC_CONFIG, "tcp/ssl: openssl version does not support disabling TLSv1.2 as required by gv->config\n");
 | 
			
		||||
          goto fail;
 | 
			
		||||
#endif
 | 
			
		||||
          break;
 | 
			
		||||
        default:
 | 
			
		||||
          DDS_LOG (DDS_LC_ERROR | DDS_LC_CONFIG, "tcp/ssl: can't set minimum requested TLS version to %d.%d\n", gv->config.ssl_min_version.major, gv->config.ssl_min_version.minor);
 | 
			
		||||
          GVLOG (DDS_LC_ERROR | DDS_LC_CONFIG, "tcp/ssl: can't set minimum requested TLS version to %d.%d\n", gv->config.ssl_min_version.major, gv->config.ssl_min_version.minor);
 | 
			
		||||
          goto fail;
 | 
			
		||||
      }
 | 
			
		||||
      break;
 | 
			
		||||
    default:
 | 
			
		||||
      DDS_LOG (DDS_LC_ERROR | DDS_LC_CONFIG, "tcp/ssl: can't set minimum requested TLS version to %d.%d\n", gv->config.ssl_min_version.major, gv->config.ssl_min_version.minor);
 | 
			
		||||
      GVLOG (DDS_LC_ERROR | DDS_LC_CONFIG, "tcp/ssl: can't set minimum requested TLS version to %d.%d\n", gv->config.ssl_min_version.major, gv->config.ssl_min_version.minor);
 | 
			
		||||
      goto fail;
 | 
			
		||||
  }
 | 
			
		||||
  SSL_CTX_set_options (ctx, SSL_OP_ALL | SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1 | disallow_TLSv1_2);
 | 
			
		||||
| 
						 | 
				
			
			@ -281,18 +281,18 @@ fail:
 | 
			
		|||
  return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void dds_report_tls_version (const SSL *ssl, const char *oper)
 | 
			
		||||
static void dds_report_tls_version (const struct q_globals *gv, const SSL *ssl, const char *oper)
 | 
			
		||||
{
 | 
			
		||||
  if (ssl)
 | 
			
		||||
  {
 | 
			
		||||
    char issuer[256], subject[256];
 | 
			
		||||
    X509_NAME_oneline (X509_get_issuer_name (SSL_get_peer_certificate (ssl)), issuer, sizeof (issuer));
 | 
			
		||||
    X509_NAME_oneline (X509_get_subject_name (SSL_get_peer_certificate (ssl)), subject, sizeof (subject));
 | 
			
		||||
    DDS_TRACE("tcp/ssl %s %s issued by %s [%s]\n", oper, subject, issuer, SSL_get_version (ssl));
 | 
			
		||||
    GVTRACE ("tcp/ssl %s %s issued by %s [%s]\n", oper, subject, issuer, SSL_get_version (ssl));
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static SSL *ddsi_ssl_connect (ddsrt_socket_t sock)
 | 
			
		||||
static SSL *ddsi_ssl_connect (const struct q_globals *gv, ddsrt_socket_t sock)
 | 
			
		||||
{
 | 
			
		||||
  SSL *ssl;
 | 
			
		||||
  int err;
 | 
			
		||||
| 
						 | 
				
			
			@ -308,11 +308,11 @@ static SSL *ddsi_ssl_connect (ddsrt_socket_t sock)
 | 
			
		|||
  err = SSL_connect (ssl);
 | 
			
		||||
  if (err != 1)
 | 
			
		||||
  {
 | 
			
		||||
    ddsi_ssl_error (ssl, "connect failed", err);
 | 
			
		||||
    ddsi_ssl_error (gv, ssl, "connect failed", err);
 | 
			
		||||
    SSL_free (ssl);
 | 
			
		||||
    ssl = NULL;
 | 
			
		||||
  }
 | 
			
		||||
  dds_report_tls_version (ssl, "connected to");
 | 
			
		||||
  dds_report_tls_version (gv, ssl, "connected to");
 | 
			
		||||
  return ssl;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -326,7 +326,7 @@ static BIO *ddsi_ssl_listen (ddsrt_socket_t sock)
 | 
			
		|||
  return bio;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static SSL *ddsi_ssl_accept (BIO *bio, ddsrt_socket_t *sock)
 | 
			
		||||
static SSL *ddsi_ssl_accept (const struct q_globals *gv, BIO *bio, ddsrt_socket_t *sock)
 | 
			
		||||
{
 | 
			
		||||
  SSL *ssl = NULL;
 | 
			
		||||
  BIO *nbio;
 | 
			
		||||
| 
						 | 
				
			
			@ -346,7 +346,7 @@ static SSL *ddsi_ssl_accept (BIO *bio, ddsrt_socket_t *sock)
 | 
			
		|||
      ssl = NULL;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  dds_report_tls_version (ssl, "accepted from");
 | 
			
		||||
  dds_report_tls_version (gv, ssl, "accepted from");
 | 
			
		||||
  return ssl;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -133,7 +133,7 @@ static void ddsi_tcp_cache_dump (void)
 | 
			
		|||
}
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
static unsigned short get_socket_port (ddsrt_socket_t socket)
 | 
			
		||||
static unsigned short get_socket_port (struct ddsrt_log_cfg *logcfg, ddsrt_socket_t socket)
 | 
			
		||||
{
 | 
			
		||||
  struct sockaddr_storage addr;
 | 
			
		||||
  socklen_t addrlen = sizeof (addr);
 | 
			
		||||
| 
						 | 
				
			
			@ -141,7 +141,7 @@ static unsigned short get_socket_port (ddsrt_socket_t socket)
 | 
			
		|||
 | 
			
		||||
  ret = ddsrt_getsockname(socket, (struct sockaddr *)&addr, &addrlen);
 | 
			
		||||
  if (ret != DDS_RETCODE_OK) {
 | 
			
		||||
    DDS_ERROR("ddsi_tcp_get_socket_port: ddsrt_getsockname retcode %"PRId32"\n", ret);
 | 
			
		||||
    DDS_CERROR (logcfg, "ddsi_tcp_get_socket_port: ddsrt_getsockname retcode %"PRId32"\n", ret);
 | 
			
		||||
    return 0;
 | 
			
		||||
  }
 | 
			
		||||
  return ddsrt_sockaddr_get_port((struct sockaddr *)&addr);
 | 
			
		||||
| 
						 | 
				
			
			@ -150,16 +150,16 @@ static unsigned short get_socket_port (ddsrt_socket_t socket)
 | 
			
		|||
static void ddsi_tcp_conn_set_socket (ddsi_tcp_conn_t conn, ddsrt_socket_t sock)
 | 
			
		||||
{
 | 
			
		||||
  conn->m_sock = sock;
 | 
			
		||||
  conn->m_base.m_base.m_port = (sock == DDSRT_INVALID_SOCKET) ? INVALID_PORT : get_socket_port (sock);
 | 
			
		||||
  conn->m_base.m_base.m_port = (sock == DDSRT_INVALID_SOCKET) ? INVALID_PORT : get_socket_port (&conn->m_base.m_base.gv->logconfig, sock);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void ddsi_tcp_sock_free (ddsrt_socket_t sock, const char * msg)
 | 
			
		||||
static void ddsi_tcp_sock_free (const struct ddsrt_log_cfg *logcfg, ddsrt_socket_t sock, const char *msg)
 | 
			
		||||
{
 | 
			
		||||
  if (sock != DDSRT_INVALID_SOCKET)
 | 
			
		||||
  {
 | 
			
		||||
    if (msg)
 | 
			
		||||
    {
 | 
			
		||||
      DDS_LOG(DDS_LC_TCP, "tcp %s free socket %"PRIdSOCK"\n", msg, sock);
 | 
			
		||||
      DDS_CLOG (DDS_LC_TCP, logcfg, "tcp %s free socket %"PRIdSOCK"\n", msg, sock);
 | 
			
		||||
    }
 | 
			
		||||
    ddsrt_close (sock);
 | 
			
		||||
  }
 | 
			
		||||
| 
						 | 
				
			
			@ -202,7 +202,7 @@ static void ddsi_tcp_conn_connect (ddsi_tcp_conn_t conn, const ddsrt_msghdr_t *
 | 
			
		|||
 | 
			
		||||
    if (ret != DDS_RETCODE_OK)
 | 
			
		||||
    {
 | 
			
		||||
      ddsi_tcp_sock_free (sock, NULL);
 | 
			
		||||
      ddsi_tcp_sock_free (&conn->m_base.m_base.gv->logconfig, sock, NULL);
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
    ddsi_tcp_conn_set_socket (conn, sock);
 | 
			
		||||
| 
						 | 
				
			
			@ -210,7 +210,7 @@ static void ddsi_tcp_conn_connect (ddsi_tcp_conn_t conn, const ddsrt_msghdr_t *
 | 
			
		|||
#ifdef DDSI_INCLUDE_SSL
 | 
			
		||||
    if (fact->ddsi_tcp_ssl_plugin.connect)
 | 
			
		||||
    {
 | 
			
		||||
      conn->m_ssl = (fact->ddsi_tcp_ssl_plugin.connect) (sock);
 | 
			
		||||
      conn->m_ssl = (fact->ddsi_tcp_ssl_plugin.connect) (conn->m_base.m_base.gv, sock);
 | 
			
		||||
      if (conn->m_ssl == NULL)
 | 
			
		||||
      {
 | 
			
		||||
        ddsi_tcp_conn_set_socket (conn, DDSRT_INVALID_SOCKET);
 | 
			
		||||
| 
						 | 
				
			
			@ -220,7 +220,7 @@ static void ddsi_tcp_conn_connect (ddsi_tcp_conn_t conn, const ddsrt_msghdr_t *
 | 
			
		|||
#endif
 | 
			
		||||
 | 
			
		||||
    sockaddr_to_string_with_port(conn->m_base.m_base.gv, buff, sizeof(buff), (struct sockaddr *) msg->msg_name);
 | 
			
		||||
    DDS_LOG(DDS_LC_TCP, "tcp connect socket %"PRIdSOCK" port %u to %s\n", sock, get_socket_port (sock), buff);
 | 
			
		||||
    DDS_CLOG (DDS_LC_TCP, &conn->m_base.m_base.gv->logconfig, "tcp connect socket %"PRIdSOCK" port %u to %s\n", sock, get_socket_port (&conn->m_base.m_base.gv->logconfig, sock), buff);
 | 
			
		||||
 | 
			
		||||
    /* Also may need to receive on connection so add to waitset */
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -268,7 +268,7 @@ static void ddsi_tcp_cache_add (struct ddsi_tran_factory_tcp *fact, ddsi_tcp_con
 | 
			
		|||
  }
 | 
			
		||||
 | 
			
		||||
  sockaddr_to_string_with_port(fact->fact.gv, buff, sizeof(buff), (struct sockaddr *)&conn->m_peer_addr);
 | 
			
		||||
  DDS_LOG(DDS_LC_TCP, "tcp cache %s %s socket %"PRIdSOCK" to %s\n", action, conn->m_base.m_server ? "server" : "client", conn->m_sock, buff);
 | 
			
		||||
  DDS_CLOG (DDS_LC_TCP, &fact->fact.gv->logconfig, "tcp cache %s %s socket %"PRIdSOCK" to %s\n", action, conn->m_base.m_server ? "server" : "client", conn->m_sock, buff);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void ddsi_tcp_cache_remove (ddsi_tcp_conn_t conn)
 | 
			
		||||
| 
						 | 
				
			
			@ -283,7 +283,7 @@ static void ddsi_tcp_cache_remove (ddsi_tcp_conn_t conn)
 | 
			
		|||
  if (node)
 | 
			
		||||
  {
 | 
			
		||||
    sockaddr_to_string_with_port(fact->fact.gv, buff, sizeof(buff), (struct sockaddr *)&conn->m_peer_addr);
 | 
			
		||||
    DDS_LOG(DDS_LC_TCP, "tcp cache removed socket %"PRIdSOCK" to %s\n", conn->m_sock, buff);
 | 
			
		||||
    DDS_CLOG (DDS_LC_TCP, &conn->m_base.m_base.gv->logconfig, "tcp cache removed socket %"PRIdSOCK" to %s\n", conn->m_sock, buff);
 | 
			
		||||
    ddsrt_avl_delete_dpath (&ddsi_tcp_treedef, &fact->ddsi_tcp_cache_g, node, &path);
 | 
			
		||||
    ddsi_tcp_node_free (node);
 | 
			
		||||
  }
 | 
			
		||||
| 
						 | 
				
			
			@ -350,7 +350,7 @@ static ssize_t ddsi_tcp_conn_read_ssl (ddsi_tcp_conn_t tcp, void * buf, size_t l
 | 
			
		|||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
static bool ddsi_tcp_select (ddsrt_socket_t sock, bool read, size_t pos, int64_t timeout)
 | 
			
		||||
static bool ddsi_tcp_select (const struct ddsrt_log_cfg *logcfg, ddsrt_socket_t sock, bool read, size_t pos, int64_t timeout)
 | 
			
		||||
{
 | 
			
		||||
  dds_return_t rc;
 | 
			
		||||
  fd_set fds;
 | 
			
		||||
| 
						 | 
				
			
			@ -368,14 +368,14 @@ static bool ddsi_tcp_select (ddsrt_socket_t sock, bool read, size_t pos, int64_t
 | 
			
		|||
  DDSRT_WARNING_GNUC_ON(sign-conversion)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
  DDS_LOG(DDS_LC_TCP, "tcp blocked %s: sock %d\n", read ? "read" : "write", (int) sock);
 | 
			
		||||
  DDS_CLOG (DDS_LC_TCP, logcfg, "tcp blocked %s: sock %d\n", read ? "read" : "write", (int) sock);
 | 
			
		||||
  do {
 | 
			
		||||
    rc = ddsrt_select (sock + 1, rdset, wrset, NULL, tval, &ready);
 | 
			
		||||
  } while (rc == DDS_RETCODE_INTERRUPTED);
 | 
			
		||||
 | 
			
		||||
  if (rc != DDS_RETCODE_OK)
 | 
			
		||||
  {
 | 
			
		||||
    DDS_WARNING ("tcp abandoning %s on blocking socket %d after %"PRIuSIZE" bytes\n", read ? "read" : "write", (int) sock, pos);
 | 
			
		||||
    DDS_CWARNING (logcfg, "tcp abandoning %s on blocking socket %d after %"PRIuSIZE" bytes\n", read ? "read" : "write", (int) sock, pos);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return (ready > 0);
 | 
			
		||||
| 
						 | 
				
			
			@ -416,7 +416,7 @@ static ssize_t ddsi_tcp_conn_read (ddsi_tran_conn_t conn, unsigned char *buf, si
 | 
			
		|||
    }
 | 
			
		||||
    else if (n == 0)
 | 
			
		||||
    {
 | 
			
		||||
      DDS_LOG(DDS_LC_TCP, "tcp read: sock %"PRIdSOCK" closed-by-peer\n", tcp->m_sock);
 | 
			
		||||
      DDS_CLOG (DDS_LC_TCP, &conn->m_base.gv->logconfig, "tcp read: sock %"PRIdSOCK" closed-by-peer\n", tcp->m_sock);
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
| 
						 | 
				
			
			@ -428,12 +428,12 @@ static ssize_t ddsi_tcp_conn_read (ddsi_tran_conn_t conn, unsigned char *buf, si
 | 
			
		|||
          if (allow_spurious && pos == 0)
 | 
			
		||||
            return 0;
 | 
			
		||||
          const int64_t timeout = conn->m_base.gv->config.tcp_read_timeout;
 | 
			
		||||
          if (ddsi_tcp_select (tcp->m_sock, true, pos, timeout) == false)
 | 
			
		||||
          if (ddsi_tcp_select (&conn->m_base.gv->logconfig, tcp->m_sock, true, pos, timeout) == false)
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
          DDS_LOG(DDS_LC_TCP, "tcp read: sock %"PRIdSOCK" error %"PRId32"\n", tcp->m_sock, rc);
 | 
			
		||||
          DDS_CLOG (DDS_LC_TCP, &conn->m_base.gv->logconfig, "tcp read: sock %"PRIdSOCK" error %"PRId32"\n", tcp->m_sock, rc);
 | 
			
		||||
          break;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
| 
						 | 
				
			
			@ -487,14 +487,14 @@ static ssize_t ddsi_tcp_block_write (ssize_t (*wr) (ddsi_tcp_conn_t, const void
 | 
			
		|||
        if (rc == DDS_RETCODE_TRY_AGAIN)
 | 
			
		||||
        {
 | 
			
		||||
          const int64_t timeout = conn->m_base.m_base.gv->config.tcp_write_timeout;
 | 
			
		||||
          if (ddsi_tcp_select (conn->m_sock, false, pos, timeout) == false)
 | 
			
		||||
          if (ddsi_tcp_select (&conn->m_base.m_base.gv->logconfig, conn->m_sock, false, pos, timeout) == false)
 | 
			
		||||
          {
 | 
			
		||||
            break;
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
          DDS_LOG(DDS_LC_TCP, "tcp write: sock %"PRIdSOCK" error %"PRId32"\n", conn->m_sock, rc);
 | 
			
		||||
          DDS_CLOG (DDS_LC_TCP, &conn->m_base.m_base.gv->logconfig, "tcp write: sock %"PRIdSOCK" error %"PRId32"\n", conn->m_sock, rc);
 | 
			
		||||
          break;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
| 
						 | 
				
			
			@ -569,7 +569,7 @@ static ssize_t ddsi_tcp_conn_write (ddsi_tran_conn_t base, const nn_locator_t *d
 | 
			
		|||
 | 
			
		||||
  if (!connect && ((flags & DDSI_TRAN_ON_CONNECT) != 0))
 | 
			
		||||
  {
 | 
			
		||||
    DDS_LOG(DDS_LC_TCP, "tcp write: sock %"PRIdSOCK" message filtered\n", conn->m_sock);
 | 
			
		||||
    DDS_CLOG (DDS_LC_TCP, &conn->m_base.m_base.gv->logconfig, "tcp write: sock %"PRIdSOCK" message filtered\n", conn->m_sock);
 | 
			
		||||
    ddsrt_mutex_unlock (&conn->m_mutex);
 | 
			
		||||
    return (ssize_t) len;
 | 
			
		||||
  }
 | 
			
		||||
| 
						 | 
				
			
			@ -628,11 +628,11 @@ static ssize_t ddsi_tcp_conn_write (ddsi_tran_conn_t base, const nn_locator_t *d
 | 
			
		|||
        {
 | 
			
		||||
          case DDS_RETCODE_NO_CONNECTION:
 | 
			
		||||
          case DDS_RETCODE_ILLEGAL_OPERATION:
 | 
			
		||||
            DDS_LOG(DDS_LC_TCP, "tcp write: sock %"PRIdSOCK" DDS_RETCODE_NO_CONNECTION\n", conn->m_sock);
 | 
			
		||||
            DDS_CLOG (DDS_LC_TCP, &conn->m_base.m_base.gv->logconfig, "tcp write: sock %"PRIdSOCK" DDS_RETCODE_NO_CONNECTION\n", conn->m_sock);
 | 
			
		||||
            break;
 | 
			
		||||
          default:
 | 
			
		||||
            if (! conn->m_base.m_closed && (conn->m_sock != DDSRT_INVALID_SOCKET))
 | 
			
		||||
              DDS_WARNING("tcp write failed on socket %"PRIdSOCK" with errno %"PRId32"\n", conn->m_sock, rc);
 | 
			
		||||
              DDS_CWARNING (&conn->m_base.m_base.gv->logconfig, "tcp write failed on socket %"PRIdSOCK" with errno %"PRId32"\n", conn->m_sock, rc);
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
| 
						 | 
				
			
			@ -641,7 +641,7 @@ static ssize_t ddsi_tcp_conn_write (ddsi_tran_conn_t base, const nn_locator_t *d
 | 
			
		|||
    {
 | 
			
		||||
      if (ret == 0)
 | 
			
		||||
      {
 | 
			
		||||
        DDS_LOG(DDS_LC_TCP, "tcp write: sock %"PRIdSOCK" eof\n", conn->m_sock);
 | 
			
		||||
        DDS_CLOG (DDS_LC_TCP, &conn->m_base.m_base.gv->logconfig, "tcp write: sock %"PRIdSOCK" eof\n", conn->m_sock);
 | 
			
		||||
      }
 | 
			
		||||
      piecewise = (ret > 0 && (size_t) ret < len);
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -753,7 +753,7 @@ static ddsi_tran_conn_t ddsi_tcp_accept (ddsi_tran_listener_t listener)
 | 
			
		|||
#ifdef DDSI_INCLUDE_SSL
 | 
			
		||||
    if (fact->ddsi_tcp_ssl_plugin.accept)
 | 
			
		||||
    {
 | 
			
		||||
      ssl = (fact->ddsi_tcp_ssl_plugin.accept) (tl->m_bio, &sock);
 | 
			
		||||
      ssl = (fact->ddsi_tcp_ssl_plugin.accept) (listener->m_base.gv, tl->m_bio, &sock);
 | 
			
		||||
      if (ssl == NULL) {
 | 
			
		||||
        assert(sock == DDSRT_INVALID_SOCKET);
 | 
			
		||||
        rc = DDS_RETCODE_ERROR;
 | 
			
		||||
| 
						 | 
				
			
			@ -766,7 +766,7 @@ static ddsi_tran_conn_t ddsi_tcp_accept (ddsi_tran_listener_t listener)
 | 
			
		|||
    }
 | 
			
		||||
    if (!ddsrt_atomic_ld32(&listener->m_base.gv->rtps_keepgoing))
 | 
			
		||||
    {
 | 
			
		||||
      ddsi_tcp_sock_free (sock, NULL);
 | 
			
		||||
      ddsi_tcp_sock_free (&listener->m_base.gv->logconfig, sock, NULL);
 | 
			
		||||
      return NULL;
 | 
			
		||||
    }
 | 
			
		||||
  } while (rc == DDS_RETCODE_INTERRUPTED || rc == DDS_RETCODE_TRY_AGAIN);
 | 
			
		||||
| 
						 | 
				
			
			@ -775,17 +775,17 @@ static ddsi_tran_conn_t ddsi_tcp_accept (ddsi_tran_listener_t listener)
 | 
			
		|||
  {
 | 
			
		||||
    (void)ddsrt_getsockname (tl->m_sock, (struct sockaddr *) &addr, &addrlen);
 | 
			
		||||
    sockaddr_to_string_with_port(fact->fact.gv, buff, sizeof(buff), (struct sockaddr *)&addr);
 | 
			
		||||
    DDS_LOG((rc == DDS_RETCODE_OK) ? DDS_LC_ERROR : DDS_LC_FATAL, "tcp accept failed on socket %"PRIdSOCK" at %s retcode %"PRId32"\n", tl->m_sock, buff, rc);
 | 
			
		||||
    DDS_CLOG ((rc == DDS_RETCODE_OK) ? DDS_LC_ERROR : DDS_LC_FATAL, &listener->m_base.gv->logconfig, "tcp accept failed on socket %"PRIdSOCK" at %s retcode %"PRId32"\n", tl->m_sock, buff, rc);
 | 
			
		||||
  }
 | 
			
		||||
  else if (getpeername (sock, (struct sockaddr *) &addr, &addrlen) == -1)
 | 
			
		||||
  {
 | 
			
		||||
    DDS_WARNING("tcp accepted new socket %"PRIdSOCK" on socket %"PRIdSOCK" but no peer address, errno %"PRId32"\n", sock, tl->m_sock, rc);
 | 
			
		||||
    DDS_CWARNING (&listener->m_base.gv->logconfig, "tcp accepted new socket %"PRIdSOCK" on socket %"PRIdSOCK" but no peer address, errno %"PRId32"\n", sock, tl->m_sock, rc);
 | 
			
		||||
    ddsrt_close (sock);
 | 
			
		||||
  }
 | 
			
		||||
  else
 | 
			
		||||
  {
 | 
			
		||||
    sockaddr_to_string_with_port(fact->fact.gv, buff, sizeof(buff), (struct sockaddr *)&addr);
 | 
			
		||||
    DDS_LOG(DDS_LC_TCP, "tcp accept new socket %"PRIdSOCK" on socket %"PRIdSOCK" from %s\n", sock, tl->m_sock, buff);
 | 
			
		||||
    DDS_CLOG (DDS_LC_TCP, &listener->m_base.gv->logconfig, "tcp accept new socket %"PRIdSOCK" on socket %"PRIdSOCK" from %s\n", sock, tl->m_sock, buff);
 | 
			
		||||
 | 
			
		||||
    (void)ddsrt_setsocknonblocking (sock, true);
 | 
			
		||||
    tcp = ddsi_tcp_new_conn (fact, sock, true, (struct sockaddr *)&addr);
 | 
			
		||||
| 
						 | 
				
			
			@ -823,7 +823,7 @@ static void ddsi_tcp_conn_peer_locator (ddsi_tran_conn_t conn, nn_locator_t * lo
 | 
			
		|||
  assert (tc->m_sock != DDSRT_INVALID_SOCKET);
 | 
			
		||||
  ddsi_ipaddr_to_loc (loc, (struct sockaddr *)&tc->m_peer_addr, tc->m_peer_addr.ss_family == AF_INET ? NN_LOCATOR_KIND_TCPv4 : NN_LOCATOR_KIND_TCPv6);
 | 
			
		||||
  ddsi_locator_to_string(conn->m_base.gv, buff, sizeof(buff), loc);
 | 
			
		||||
  DDS_LOG(DDS_LC_TCP, "(tcp EP:%s)", buff);
 | 
			
		||||
  DDS_CLOG (DDS_LC_TCP, &conn->m_base.gv->logconfig, "(tcp EP:%s)", buff);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void ddsi_tcp_base_init (const struct ddsi_tran_factory_tcp *fact, struct ddsi_tran_conn *base)
 | 
			
		||||
| 
						 | 
				
			
			@ -880,21 +880,21 @@ static ddsi_tran_listener_t ddsi_tcp_create_listener (ddsi_tran_factory_t fact,
 | 
			
		|||
    tl->m_base.m_accept_fn = ddsi_tcp_accept;
 | 
			
		||||
    tl->m_base.m_factory = fact;
 | 
			
		||||
 | 
			
		||||
    tl->m_base.m_base.m_port = get_socket_port (sock);
 | 
			
		||||
    tl->m_base.m_base.m_port = get_socket_port (&fact->gv->logconfig, sock);
 | 
			
		||||
    tl->m_base.m_base.m_trantype = DDSI_TRAN_LISTENER;
 | 
			
		||||
    tl->m_base.m_base.m_handle_fn = ddsi_tcp_listener_handle;
 | 
			
		||||
    tl->m_base.m_locator_fn = ddsi_tcp_locator;
 | 
			
		||||
 | 
			
		||||
    ret = ddsrt_getsockname(sock, (struct sockaddr *)&addr, &addrlen);
 | 
			
		||||
    if (ret != DDS_RETCODE_OK) {
 | 
			
		||||
        DDS_ERROR("ddsi_tcp_create_listener: ddsrt_getsockname returned %"PRId32"\n", ret);
 | 
			
		||||
        ddsi_tcp_sock_free(sock, NULL);
 | 
			
		||||
        DDS_CERROR (&fact->gv->logconfig, "ddsi_tcp_create_listener: ddsrt_getsockname returned %"PRId32"\n", ret);
 | 
			
		||||
        ddsi_tcp_sock_free(&fact->gv->logconfig, sock, NULL);
 | 
			
		||||
        ddsrt_free(tl);
 | 
			
		||||
        return NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    sockaddr_to_string_with_port(fact->gv, buff, sizeof(buff), (struct sockaddr *)&addr);
 | 
			
		||||
    DDS_LOG(DDS_LC_TCP, "tcp create listener socket %"PRIdSOCK" on %s\n", sock, buff);
 | 
			
		||||
    DDS_CLOG (DDS_LC_TCP, &fact->gv->logconfig, "tcp create listener socket %"PRIdSOCK" on %s\n", sock, buff);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return tl ? &tl->m_base : NULL;
 | 
			
		||||
| 
						 | 
				
			
			@ -907,7 +907,7 @@ static void ddsi_tcp_conn_delete (ddsi_tcp_conn_t conn)
 | 
			
		|||
#endif
 | 
			
		||||
  char buff[DDSI_LOCSTRLEN];
 | 
			
		||||
  sockaddr_to_string_with_port(conn->m_base.m_base.gv, buff, sizeof(buff), (struct sockaddr *)&conn->m_peer_addr);
 | 
			
		||||
  DDS_LOG(DDS_LC_TCP, "tcp free %s connnection on socket %"PRIdSOCK" to %s\n", conn->m_base.m_server ? "server" : "client", conn->m_sock, buff);
 | 
			
		||||
  DDS_CLOG (DDS_LC_TCP, &conn->m_base.m_base.gv->logconfig, "tcp free %s connnection on socket %"PRIdSOCK" to %s\n", conn->m_base.m_server ? "server" : "client", conn->m_sock, buff);
 | 
			
		||||
 | 
			
		||||
#ifdef DDSI_INCLUDE_SSL
 | 
			
		||||
  if (fact->ddsi_tcp_ssl_plugin.ssl_free)
 | 
			
		||||
| 
						 | 
				
			
			@ -917,7 +917,7 @@ static void ddsi_tcp_conn_delete (ddsi_tcp_conn_t conn)
 | 
			
		|||
  else
 | 
			
		||||
#endif
 | 
			
		||||
  {
 | 
			
		||||
    ddsi_tcp_sock_free (conn->m_sock, "connection");
 | 
			
		||||
    ddsi_tcp_sock_free (&conn->m_base.m_base.gv->logconfig, conn->m_sock, "connection");
 | 
			
		||||
  }
 | 
			
		||||
  ddsrt_mutex_destroy (&conn->m_mutex);
 | 
			
		||||
  ddsrt_free (conn);
 | 
			
		||||
| 
						 | 
				
			
			@ -932,7 +932,7 @@ static void ddsi_tcp_close_conn (ddsi_tran_conn_t tc)
 | 
			
		|||
    nn_locator_t loc;
 | 
			
		||||
    ddsi_tcp_conn_t conn = (ddsi_tcp_conn_t) tc;
 | 
			
		||||
    sockaddr_to_string_with_port(tc->m_base.gv, buff, sizeof(buff), (struct sockaddr *)&conn->m_peer_addr);
 | 
			
		||||
    DDS_LOG(DDS_LC_TCP, "tcp close %s connnection on socket %"PRIdSOCK" to %s\n", conn->m_base.m_server ? "server" : "client", conn->m_sock, buff);
 | 
			
		||||
    DDS_CLOG (DDS_LC_TCP, &tc->m_base.gv->logconfig, "tcp close %s connnection on socket %"PRIdSOCK" to %s\n", conn->m_base.m_server ? "server" : "client", conn->m_sock, buff);
 | 
			
		||||
    (void) shutdown (conn->m_sock, 2);
 | 
			
		||||
    ddsi_ipaddr_to_loc(&loc, (struct sockaddr *)&conn->m_peer_addr, conn->m_peer_addr.ss_family == AF_INET ? NN_LOCATOR_KIND_TCPv4 : NN_LOCATOR_KIND_TCPv6);
 | 
			
		||||
    loc.port = conn->m_peer_port;
 | 
			
		||||
| 
						 | 
				
			
			@ -964,7 +964,7 @@ static void ddsi_tcp_unblock_listener (ddsi_tran_listener_t listener)
 | 
			
		|||
 | 
			
		||||
    ret = ddsrt_getsockname(tl->m_sock, (struct sockaddr *)&addr, &addrlen);
 | 
			
		||||
    if (ret != DDS_RETCODE_OK) {
 | 
			
		||||
      DDS_WARNING("tcp failed to get listener address error %"PRId32"\n", ret);
 | 
			
		||||
      DDS_CWARNING (&listener->m_base.gv->logconfig, "tcp failed to get listener address error %"PRId32"\n", ret);
 | 
			
		||||
    } else {
 | 
			
		||||
      switch (addr.ss_family) {
 | 
			
		||||
        case AF_INET:
 | 
			
		||||
| 
						 | 
				
			
			@ -994,10 +994,10 @@ static void ddsi_tcp_unblock_listener (ddsi_tran_listener_t listener)
 | 
			
		|||
      {
 | 
			
		||||
        char buff[DDSI_LOCSTRLEN];
 | 
			
		||||
        sockaddr_to_string_with_port(listener->m_base.gv, buff, sizeof(buff), (struct sockaddr *)&addr);
 | 
			
		||||
        DDS_WARNING("tcp failed to connect to own listener (%s) error %"PRId32"\n", buff, ret);
 | 
			
		||||
        DDS_CWARNING (&listener->m_base.gv->logconfig, "tcp failed to connect to own listener (%s) error %"PRId32"\n", buff, ret);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    ddsi_tcp_sock_free (sock, NULL);
 | 
			
		||||
    ddsi_tcp_sock_free (&listener->m_base.gv->logconfig, sock, NULL);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1011,7 +1011,7 @@ static void ddsi_tcp_release_listener (ddsi_tran_listener_t listener)
 | 
			
		|||
    (fact->ddsi_tcp_ssl_plugin.bio_vfree) (tl->m_bio);
 | 
			
		||||
  }
 | 
			
		||||
#endif
 | 
			
		||||
  ddsi_tcp_sock_free (tl->m_sock, "listener");
 | 
			
		||||
  ddsi_tcp_sock_free (&listener->m_base.gv->logconfig, tl->m_sock, "listener");
 | 
			
		||||
  ddsrt_free (tl);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1026,8 +1026,8 @@ static void ddsi_tcp_release_factory (struct ddsi_tran_factory *fact_cmn)
 | 
			
		|||
    (fact->ddsi_tcp_ssl_plugin.fini) ();
 | 
			
		||||
  }
 | 
			
		||||
#endif
 | 
			
		||||
  DDS_CLOG (DDS_LC_CONFIG, &fact_cmn->gv->logconfig, "tcp de-initialized\n");
 | 
			
		||||
  ddsrt_free (fact);
 | 
			
		||||
  DDS_LOG(DDS_LC_CONFIG, "tcp de-initialized\n");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static enum ddsi_locator_from_string_result ddsi_tcp_address_from_string (ddsi_tran_factory_t fact, nn_locator_t *loc, const char *str)
 | 
			
		||||
| 
						 | 
				
			
			@ -1097,7 +1097,7 @@ int ddsi_tcp_init (struct q_globals *gv)
 | 
			
		|||
    ddsi_ssl_config_plugin (&fact->ddsi_tcp_ssl_plugin);
 | 
			
		||||
    if (! fact->ddsi_tcp_ssl_plugin.init (gv))
 | 
			
		||||
    {
 | 
			
		||||
      DDS_ERROR("Failed to initialize OpenSSL\n");
 | 
			
		||||
      GVERROR ("Failed to initialize OpenSSL\n");
 | 
			
		||||
      return -1;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
| 
						 | 
				
			
			@ -1106,6 +1106,6 @@ int ddsi_tcp_init (struct q_globals *gv)
 | 
			
		|||
  ddsrt_avl_init (&ddsi_tcp_treedef, &fact->ddsi_tcp_cache_g);
 | 
			
		||||
  ddsrt_mutex_init (&fact->ddsi_tcp_cache_lock_g);
 | 
			
		||||
 | 
			
		||||
  DDS_LOG(DDS_LC_CONFIG, "tcp initialized\n");
 | 
			
		||||
  GVLOG (DDS_LC_CONFIG, "tcp initialized\n");
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -14,6 +14,7 @@
 | 
			
		|||
#include "dds/ddsrt/heap.h"
 | 
			
		||||
#include "dds/ddsrt/sync.h"
 | 
			
		||||
#include "dds/ddsrt/threads.h"
 | 
			
		||||
#include "dds/ddsrt/hopscotch.h"
 | 
			
		||||
 | 
			
		||||
#include "dds/ddsi/ddsi_threadmon.h"
 | 
			
		||||
#include "dds/ddsi/q_config.h"
 | 
			
		||||
| 
						 | 
				
			
			@ -29,6 +30,13 @@ struct alive_vt {
 | 
			
		|||
  vtime_t vt;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct threadmon_domain {
 | 
			
		||||
  const struct q_globals *gv;
 | 
			
		||||
  unsigned n_not_alive;
 | 
			
		||||
  size_t msgpos;
 | 
			
		||||
  char msg[2048];
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct ddsi_threadmon {
 | 
			
		||||
  int keepgoing;
 | 
			
		||||
  struct alive_vt *av_ary;
 | 
			
		||||
| 
						 | 
				
			
			@ -40,20 +48,28 @@ struct ddsi_threadmon {
 | 
			
		|||
  ddsrt_mutex_t lock;
 | 
			
		||||
  ddsrt_cond_t cond;
 | 
			
		||||
  struct thread_state1 *ts;
 | 
			
		||||
  struct ddsrt_hh *domains;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static struct threadmon_domain *find_domain (struct ddsi_threadmon *sl, const struct q_globals *gv)
 | 
			
		||||
{
 | 
			
		||||
  struct threadmon_domain dummy;
 | 
			
		||||
  dummy.gv = gv;
 | 
			
		||||
  return ddsrt_hh_lookup (sl->domains, &dummy);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static uint32_t threadmon_thread (struct ddsi_threadmon *sl)
 | 
			
		||||
{
 | 
			
		||||
  /* Do not check more often than once every 100ms (no particular
 | 
			
		||||
     reason why it has to be 100ms), regardless of the lease settings.
 | 
			
		||||
     Note: can't trust sl->self, may have been scheduled before the
 | 
			
		||||
     assignment. */
 | 
			
		||||
  nn_mtime_t next_thread_cputime = { 0 };
 | 
			
		||||
  nn_mtime_t tlast = { 0 };
 | 
			
		||||
  bool was_alive = true;
 | 
			
		||||
  for (uint32_t i = 0; i < thread_states.nthreads; i++)
 | 
			
		||||
  {
 | 
			
		||||
    sl->av_ary[i].alive = true;
 | 
			
		||||
    sl->av_ary[i].vt = 0;
 | 
			
		||||
  }
 | 
			
		||||
  ddsrt_mutex_lock (&sl->lock);
 | 
			
		||||
  while (sl->keepgoing)
 | 
			
		||||
| 
						 | 
				
			
			@ -61,89 +77,126 @@ static uint32_t threadmon_thread (struct ddsi_threadmon *sl)
 | 
			
		|||
    /* Guard against spurious wakeups by checking only when cond_waitfor signals a timeout */
 | 
			
		||||
    if (ddsrt_cond_waitfor (&sl->cond, &sl->lock, sl->liveliness_monitoring_interval))
 | 
			
		||||
      continue;
 | 
			
		||||
 | 
			
		||||
    unsigned n_alive = 0, n_unused = 0;
 | 
			
		||||
    nn_mtime_t tnow = now_mt ();
 | 
			
		||||
 | 
			
		||||
    LOG_THREAD_CPUTIME (next_thread_cputime);
 | 
			
		||||
 | 
			
		||||
    DDS_TRACE("threadmon: tnow %"PRId64":", tnow.v);
 | 
			
		||||
 | 
			
		||||
    /* Check progress only if enough time has passed: there is no
 | 
			
		||||
       guarantee that os_cond_timedwait wont ever return early, and we
 | 
			
		||||
       do want to avoid spurious warnings. */
 | 
			
		||||
    nn_mtime_t tnow = now_mt ();
 | 
			
		||||
    if (tnow.v < tlast.v)
 | 
			
		||||
      continue;
 | 
			
		||||
 | 
			
		||||
    /* Scan threads to classify them as alive (sleeping or making progress) or dead (stuck in the same
 | 
			
		||||
       "awake" state), ignoring those used in domains that do not have a liveliness monitoring enabled
 | 
			
		||||
       (in which case find_domain returns a null pointer).
 | 
			
		||||
 | 
			
		||||
       A non-awake thread is not really bound to a domain, but it is mostly ignored because it is
 | 
			
		||||
       considered "alive".  An awake one may be switching to another domain immediately after loading
 | 
			
		||||
       the domain here, but in that case it is making progress -- and so also mostly ignored.  (This
 | 
			
		||||
       is a similar argument to that used for the GC). */
 | 
			
		||||
    unsigned n_not_alive = 0;
 | 
			
		||||
    tlast = tnow;
 | 
			
		||||
    for (uint32_t i = 0; i < thread_states.nthreads; i++)
 | 
			
		||||
    {
 | 
			
		||||
      n_alive = thread_states.nthreads;
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
      tlast = tnow;
 | 
			
		||||
      for (uint32_t i = 0; i < thread_states.nthreads; i++)
 | 
			
		||||
      if (thread_states.ts[i].state == THREAD_STATE_ZERO)
 | 
			
		||||
        continue;
 | 
			
		||||
 | 
			
		||||
      vtime_t vt = ddsrt_atomic_ld32 (&thread_states.ts[i].vtime);
 | 
			
		||||
      ddsrt_atomic_fence_ldld ();
 | 
			
		||||
      struct q_globals const * const gv = ddsrt_atomic_ldvoidp (&thread_states.ts[i].gv);
 | 
			
		||||
      struct threadmon_domain *tmdom = find_domain (sl, gv);
 | 
			
		||||
      if (tmdom == NULL)
 | 
			
		||||
        continue;
 | 
			
		||||
 | 
			
		||||
      bool alive = vtime_asleep_p (vt) || vtime_asleep_p (sl->av_ary[i].vt) || vtime_gt (vt, sl->av_ary[i].vt);
 | 
			
		||||
      n_not_alive += (unsigned) !alive;
 | 
			
		||||
      tmdom->n_not_alive += (unsigned) !alive;
 | 
			
		||||
 | 
			
		||||
      /* Construct a detailed trace line for domains that have tracing enabled, domains that don't
 | 
			
		||||
         only get "failed to make progress"/"once again made progress" messages */
 | 
			
		||||
      if (tmdom->msgpos < sizeof (tmdom->msg) && (gv->logconfig.c.mask & DDS_LC_TRACE))
 | 
			
		||||
      {
 | 
			
		||||
        if (thread_states.ts[i].state == THREAD_STATE_ZERO)
 | 
			
		||||
          n_unused++;
 | 
			
		||||
        tmdom->msgpos +=
 | 
			
		||||
          (size_t) snprintf (tmdom->msg + tmdom->msgpos, sizeof (tmdom->msg) - tmdom->msgpos,
 | 
			
		||||
                             " %u(%s):%c:%"PRIx32"->%"PRIx32, i, thread_states.ts[i].name, alive ? 'a' : 'd', sl->av_ary[i].vt, vt);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      sl->av_ary[i].vt = vt;
 | 
			
		||||
      if (sl->av_ary[i].alive != alive)
 | 
			
		||||
      {
 | 
			
		||||
        const char *name = thread_states.ts[i].name;
 | 
			
		||||
        const char *msg;
 | 
			
		||||
        if (!alive)
 | 
			
		||||
          msg = "failed to make progress";
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
          vtime_t vt = ddsrt_atomic_ld32 (&thread_states.ts[i].vtime);
 | 
			
		||||
          bool alive = vtime_asleep_p (vt) || vtime_asleep_p (sl->av_ary[i].vt) || vtime_gt (vt, sl->av_ary[i].vt);
 | 
			
		||||
          n_alive += (unsigned) alive;
 | 
			
		||||
          DDS_TRACE(" %u(%s):%c:%"PRIx32"->%"PRIx32, i, thread_states.ts[i].name, alive ? 'a' : 'd', sl->av_ary[i].vt, vt);
 | 
			
		||||
          sl->av_ary[i].vt = vt;
 | 
			
		||||
          if (sl->av_ary[i].alive != alive)
 | 
			
		||||
          {
 | 
			
		||||
            const char *name = thread_states.ts[i].name;
 | 
			
		||||
            const char *msg;
 | 
			
		||||
            if (!alive)
 | 
			
		||||
              msg = "failed to make progress";
 | 
			
		||||
            else
 | 
			
		||||
              msg = "once again made progress";
 | 
			
		||||
            DDS_INFO("thread %s %s\n", name ? name : "(anon)", msg);
 | 
			
		||||
            sl->av_ary[i].alive = alive;
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
          msg = "once again made progress";
 | 
			
		||||
        DDS_CLOG (alive ? DDS_LC_INFO : DDS_LC_WARNING, &gv->logconfig, "thread %s %s\n", name ? name : "(anon)", msg);
 | 
			
		||||
        sl->av_ary[i].alive = alive;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (n_alive + n_unused == thread_states.nthreads)
 | 
			
		||||
    /* Scan all domains: there is only a single log buffer for the thread and we need the newline
 | 
			
		||||
       to flush the messages if we want to avoid mixing up domains; and we'd still like to dump
 | 
			
		||||
       stack traces only once if there are stuck threads, even though a deadlock typically involves
 | 
			
		||||
       multiple threads. */
 | 
			
		||||
    struct ddsrt_hh_iter it;
 | 
			
		||||
    for (struct threadmon_domain *tmdom = ddsrt_hh_iter_first (sl->domains, &it); tmdom != NULL; tmdom = ddsrt_hh_iter_next (&it))
 | 
			
		||||
    {
 | 
			
		||||
      DDS_TRACE(": [%u] OK\n", n_alive);
 | 
			
		||||
      was_alive = true;
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
      DDS_TRACE(": [%u] FAIL\n", n_alive);
 | 
			
		||||
      if (was_alive && dds_get_log_mask () != 0)
 | 
			
		||||
      if (tmdom->n_not_alive == 0)
 | 
			
		||||
        DDS_CTRACE (&tmdom->gv->logconfig, "%s: OK\n", tmdom->msg);
 | 
			
		||||
      else
 | 
			
		||||
      {
 | 
			
		||||
        if (!sl->noprogress_log_stacktraces)
 | 
			
		||||
          DDS_LOG (~DDS_LC_FATAL, "-- stack traces requested, but traces disabled --\n");
 | 
			
		||||
        else
 | 
			
		||||
          log_stack_traces ();
 | 
			
		||||
        DDS_CTRACE (&tmdom->gv->logconfig, "%s: FAIL (%u)\n", tmdom->msg, tmdom->n_not_alive);
 | 
			
		||||
        if (was_alive && tmdom->gv->logconfig.c.mask != 0)
 | 
			
		||||
        {
 | 
			
		||||
          if (!sl->noprogress_log_stacktraces)
 | 
			
		||||
            DDS_CLOG (~DDS_LC_FATAL, &tmdom->gv->logconfig, "-- stack traces requested, but traces disabled --\n");
 | 
			
		||||
          else
 | 
			
		||||
            log_stack_traces (&tmdom->gv->logconfig, tmdom->gv);
 | 
			
		||||
        }
 | 
			
		||||
        was_alive = false;
 | 
			
		||||
      }
 | 
			
		||||
      was_alive = false;
 | 
			
		||||
    }
 | 
			
		||||
      tmdom->n_not_alive = 0;
 | 
			
		||||
      tmdom->msgpos = 0;
 | 
			
		||||
      tmdom->msg[0] = 0;
 | 
			
		||||
 | 
			
		||||
#if DDSRT_HAVE_RUSAGE
 | 
			
		||||
    if (dds_get_log_mask() & DDS_LC_TIMING)
 | 
			
		||||
    {
 | 
			
		||||
      ddsrt_rusage_t u;
 | 
			
		||||
      if (ddsrt_getrusage (DDSRT_RUSAGE_SELF, &u) == DDS_RETCODE_OK)
 | 
			
		||||
      if (tmdom->gv->logconfig.c.mask & DDS_LC_TIMING)
 | 
			
		||||
      {
 | 
			
		||||
        DDS_LOG(DDS_LC_TIMING,
 | 
			
		||||
                "rusage: utime %d.%09d stime %d.%09d maxrss %zu data %zu vcsw %zu ivcsw %zu\n",
 | 
			
		||||
                (int) (u.utime / DDS_NSECS_IN_SEC),
 | 
			
		||||
                (int) (u.utime % DDS_NSECS_IN_SEC),
 | 
			
		||||
                (int) (u.stime / DDS_NSECS_IN_SEC),
 | 
			
		||||
                (int) (u.stime % DDS_NSECS_IN_SEC),
 | 
			
		||||
                u.maxrss, u.idrss, u.nvcsw, u.nivcsw);
 | 
			
		||||
        ddsrt_rusage_t u;
 | 
			
		||||
        if (ddsrt_getrusage (DDSRT_RUSAGE_SELF, &u) == DDS_RETCODE_OK)
 | 
			
		||||
        {
 | 
			
		||||
          DDS_CLOG (DDS_LC_TIMING, &tmdom->gv->logconfig,
 | 
			
		||||
                    "rusage: utime %d.%09d stime %d.%09d maxrss %zu data %zu vcsw %zu ivcsw %zu\n",
 | 
			
		||||
                    (int) (u.utime / DDS_NSECS_IN_SEC),
 | 
			
		||||
                    (int) (u.utime % DDS_NSECS_IN_SEC),
 | 
			
		||||
                    (int) (u.stime / DDS_NSECS_IN_SEC),
 | 
			
		||||
                    (int) (u.stime % DDS_NSECS_IN_SEC),
 | 
			
		||||
                    u.maxrss, u.idrss, u.nvcsw, u.nivcsw);
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
#endif /* DDSRT_HAVE_RUSAGE */
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    was_alive = (n_not_alive == 0);
 | 
			
		||||
  }
 | 
			
		||||
  ddsrt_mutex_unlock (&sl->lock);
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static uint32_t threadmon_domain_hash (const void *va)
 | 
			
		||||
{
 | 
			
		||||
  const struct threadmon_domain *a = va;
 | 
			
		||||
  const uint32_t u = (uint16_t) ((uintptr_t) a->gv >> 3);
 | 
			
		||||
  const uint32_t v = u * 0xb4817365;
 | 
			
		||||
  return v >> 16;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int threadmon_domain_eq (const void *va, const void *vb)
 | 
			
		||||
{
 | 
			
		||||
  const struct threadmon_domain *a = va;
 | 
			
		||||
  const struct threadmon_domain *b = vb;
 | 
			
		||||
  return a->gv == b->gv;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct ddsi_threadmon *ddsi_threadmon_new (int64_t liveliness_monitoring_interval, bool noprogress_log_stacktraces)
 | 
			
		||||
{
 | 
			
		||||
  struct ddsi_threadmon *sl;
 | 
			
		||||
| 
						 | 
				
			
			@ -153,6 +206,7 @@ struct ddsi_threadmon *ddsi_threadmon_new (int64_t liveliness_monitoring_interva
 | 
			
		|||
  sl->ts = NULL;
 | 
			
		||||
  sl->liveliness_monitoring_interval = liveliness_monitoring_interval;
 | 
			
		||||
  sl->noprogress_log_stacktraces = noprogress_log_stacktraces;
 | 
			
		||||
  sl->domains = ddsrt_hh_new (1, threadmon_domain_hash, threadmon_domain_eq);
 | 
			
		||||
 | 
			
		||||
  if ((sl->av_ary = ddsrt_malloc (thread_states.nthreads * sizeof (*sl->av_ary))) == NULL)
 | 
			
		||||
    goto fail_vtimes;
 | 
			
		||||
| 
						 | 
				
			
			@ -167,14 +221,15 @@ struct ddsi_threadmon *ddsi_threadmon_new (int64_t liveliness_monitoring_interva
 | 
			
		|||
  return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
dds_return_t ddsi_threadmon_start (struct ddsi_threadmon *sl, const char *name, const struct config_thread_properties_listelem *tprops)
 | 
			
		||||
dds_return_t ddsi_threadmon_start (struct ddsi_threadmon *sl, const char *name)
 | 
			
		||||
{
 | 
			
		||||
  ddsrt_mutex_lock (&sl->lock);
 | 
			
		||||
  assert (sl->keepgoing == -1);
 | 
			
		||||
  sl->keepgoing = 1;
 | 
			
		||||
  ddsrt_mutex_unlock (&sl->lock);
 | 
			
		||||
 | 
			
		||||
  if (create_thread_with_properties (&sl->ts, tprops, name, (uint32_t (*) (void *)) threadmon_thread, sl) != DDS_RETCODE_OK)
 | 
			
		||||
  /* FIXME: thread properties */
 | 
			
		||||
  if (create_thread_with_properties (&sl->ts, NULL, name, (uint32_t (*) (void *)) threadmon_thread, sl) != DDS_RETCODE_OK)
 | 
			
		||||
    goto fail_thread;
 | 
			
		||||
  return 0;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -183,6 +238,39 @@ dds_return_t ddsi_threadmon_start (struct ddsi_threadmon *sl, const char *name,
 | 
			
		|||
  return DDS_RETCODE_ERROR;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ddsi_threadmon_register_domain (struct ddsi_threadmon *sl, const struct q_globals *gv)
 | 
			
		||||
{
 | 
			
		||||
  if (gv->config.liveliness_monitoring)
 | 
			
		||||
  {
 | 
			
		||||
    struct threadmon_domain *tmdom = ddsrt_malloc (sizeof (*tmdom));
 | 
			
		||||
    tmdom->gv = gv;
 | 
			
		||||
    tmdom->n_not_alive = 0;
 | 
			
		||||
    tmdom->msgpos = 0;
 | 
			
		||||
    tmdom->msg[0] = 0;
 | 
			
		||||
 | 
			
		||||
    ddsrt_mutex_lock (&sl->lock);
 | 
			
		||||
    int x = ddsrt_hh_add (sl->domains, tmdom);
 | 
			
		||||
    assert (x);
 | 
			
		||||
    (void) x;
 | 
			
		||||
    ddsrt_mutex_unlock (&sl->lock);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ddsi_threadmon_unregister_domain (struct ddsi_threadmon *sl, const struct q_globals *gv)
 | 
			
		||||
{
 | 
			
		||||
  if (gv->config.liveliness_monitoring)
 | 
			
		||||
  {
 | 
			
		||||
    ddsrt_mutex_lock (&sl->lock);
 | 
			
		||||
    struct threadmon_domain dummy;
 | 
			
		||||
    dummy.gv = gv;
 | 
			
		||||
    struct threadmon_domain *tmdom = ddsrt_hh_lookup (sl->domains, &dummy);
 | 
			
		||||
    assert (tmdom);
 | 
			
		||||
    ddsrt_hh_remove (sl->domains, tmdom);
 | 
			
		||||
    ddsrt_mutex_unlock (&sl->lock);
 | 
			
		||||
    ddsrt_free (tmdom);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ddsi_threadmon_stop (struct ddsi_threadmon *sl)
 | 
			
		||||
{
 | 
			
		||||
  if (sl->keepgoing != -1)
 | 
			
		||||
| 
						 | 
				
			
			@ -197,9 +285,13 @@ void ddsi_threadmon_stop (struct ddsi_threadmon *sl)
 | 
			
		|||
 | 
			
		||||
void ddsi_threadmon_free (struct ddsi_threadmon *sl)
 | 
			
		||||
{
 | 
			
		||||
#ifndef NDEBUG
 | 
			
		||||
  struct ddsrt_hh_iter it;
 | 
			
		||||
  assert (ddsrt_hh_iter_first (sl->domains, &it) == NULL);
 | 
			
		||||
#endif
 | 
			
		||||
  ddsrt_cond_destroy (&sl->cond);
 | 
			
		||||
  ddsrt_mutex_destroy (&sl->lock);
 | 
			
		||||
  ddsrt_hh_free (sl->domains);
 | 
			
		||||
  ddsrt_free (sl->av_ary);
 | 
			
		||||
  ddsrt_free (sl);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -140,7 +140,7 @@ struct ddsi_tkmap_instance *ddsi_tkmap_find_by_id (struct ddsi_tkmap *map, uint6
 | 
			
		|||
    return tk;
 | 
			
		||||
  else
 | 
			
		||||
    /* Let key value lookup handle the possible CAS loop and the complicated cases */
 | 
			
		||||
    return ddsi_tkmap_find (map, tk->m_sample, false, false);
 | 
			
		||||
    return ddsi_tkmap_find (map, tk->m_sample, false);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Debug keyhash generation for debug and coverage builds */
 | 
			
		||||
| 
						 | 
				
			
			@ -155,7 +155,7 @@ struct ddsi_tkmap_instance *ddsi_tkmap_find_by_id (struct ddsi_tkmap *map, uint6
 | 
			
		|||
#define DDS_DEBUG_KEYHASH 1
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
struct ddsi_tkmap_instance *ddsi_tkmap_find (struct ddsi_tkmap *map, struct ddsi_serdata *sd, const bool rd, const bool create)
 | 
			
		||||
struct ddsi_tkmap_instance *ddsi_tkmap_find (struct ddsi_tkmap *map, struct ddsi_serdata *sd, const bool create)
 | 
			
		||||
{
 | 
			
		||||
  struct ddsi_tkmap_instance dummy;
 | 
			
		||||
  struct ddsi_tkmap_instance *tk;
 | 
			
		||||
| 
						 | 
				
			
			@ -198,17 +198,12 @@ retry:
 | 
			
		|||
      goto retry;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (tk && rd)
 | 
			
		||||
  {
 | 
			
		||||
    DDS_TRACE("tk=%p iid=%"PRIx64" ", (void *) tk, tk->m_iid);
 | 
			
		||||
  }
 | 
			
		||||
  return tk;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct ddsi_tkmap_instance *ddsi_tkmap_lookup_instance_ref (struct ddsi_tkmap *map, struct ddsi_serdata *sd)
 | 
			
		||||
{
 | 
			
		||||
  return ddsi_tkmap_find (map, sd, true, true);
 | 
			
		||||
  return ddsi_tkmap_find (map, sd, true);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ddsi_tkmap_instance_ref (struct ddsi_tkmap_instance *tk)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -90,13 +90,13 @@ static ssize_t ddsi_udp_conn_read (ddsi_tran_conn_t conn, unsigned char * buf, s
 | 
			
		|||
      nn_locator_t tmp;
 | 
			
		||||
      ddsi_ipaddr_to_loc(&tmp, (struct sockaddr *)&src, src.ss_family == AF_INET ? NN_LOCATOR_KIND_UDPv4 : NN_LOCATOR_KIND_UDPv6);
 | 
			
		||||
      ddsi_locator_to_string(conn->m_base.gv, addrbuf, sizeof(addrbuf), &tmp);
 | 
			
		||||
      DDS_WARNING("%s => %d truncated to %d\n", addrbuf, (int)ret, (int)len);
 | 
			
		||||
      DDS_CWARNING(&conn->m_base.gv->logconfig, "%s => %d truncated to %d\n", addrbuf, (int)ret, (int)len);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  else if (rc != DDS_RETCODE_BAD_PARAMETER &&
 | 
			
		||||
           rc != DDS_RETCODE_NO_CONNECTION)
 | 
			
		||||
  {
 | 
			
		||||
    DDS_ERROR("UDP recvmsg sock %d: ret %d retcode %"PRId32"\n", (int) ((ddsi_udp_conn_t) conn)->m_sock, (int) ret, rc);
 | 
			
		||||
    DDS_CERROR(&conn->m_base.gv->logconfig, "UDP recvmsg sock %d: ret %d retcode %"PRId32"\n", (int) ((ddsi_udp_conn_t) conn)->m_sock, (int) ret, rc);
 | 
			
		||||
    ret = -1;
 | 
			
		||||
  }
 | 
			
		||||
  return ret;
 | 
			
		||||
| 
						 | 
				
			
			@ -161,7 +161,7 @@ static ssize_t ddsi_udp_conn_write (ddsi_tran_conn_t conn, const nn_locator_t *d
 | 
			
		|||
           rc != DDS_RETCODE_NOT_ALLOWED &&
 | 
			
		||||
           rc != DDS_RETCODE_NO_CONNECTION)
 | 
			
		||||
  {
 | 
			
		||||
    DDS_ERROR("ddsi_udp_conn_write failed with retcode %"PRId32"\n", rc);
 | 
			
		||||
    DDS_CERROR(&conn->m_base.gv->logconfig, "ddsi_udp_conn_write failed with retcode %"PRId32"\n", rc);
 | 
			
		||||
  }
 | 
			
		||||
  return (rc == DDS_RETCODE_OK ? ret : -1);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -202,7 +202,7 @@ static int ddsi_udp_conn_locator (ddsi_tran_factory_t fact, ddsi_tran_base_t bas
 | 
			
		|||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static unsigned short get_socket_port (ddsrt_socket_t socket)
 | 
			
		||||
static unsigned short get_socket_port (const struct ddsrt_log_cfg *logcfg, ddsrt_socket_t socket)
 | 
			
		||||
{
 | 
			
		||||
  dds_return_t ret;
 | 
			
		||||
  struct sockaddr_storage addr;
 | 
			
		||||
| 
						 | 
				
			
			@ -211,7 +211,7 @@ static unsigned short get_socket_port (ddsrt_socket_t socket)
 | 
			
		|||
  ret = ddsrt_getsockname (socket, (struct sockaddr *)&addr, &addrlen);
 | 
			
		||||
  if (ret != DDS_RETCODE_OK)
 | 
			
		||||
  {
 | 
			
		||||
    DDS_ERROR("ddsi_udp_get_socket_port: getsockname returned %"PRId32"\n", ret);
 | 
			
		||||
    DDS_CERROR (logcfg, "ddsi_udp_get_socket_port: getsockname returned %"PRId32"\n", ret);
 | 
			
		||||
    return 0;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -242,7 +242,7 @@ static ddsi_tran_conn_t ddsi_udp_create_conn (ddsi_tran_factory_t fact, uint32_t
 | 
			
		|||
#endif
 | 
			
		||||
 | 
			
		||||
    ddsi_factory_conn_init (fact, &uc->m_base);
 | 
			
		||||
    uc->m_base.m_base.m_port = get_socket_port (sock);
 | 
			
		||||
    uc->m_base.m_base.m_port = get_socket_port (&fact->gv->logconfig, sock);
 | 
			
		||||
    uc->m_base.m_base.m_trantype = DDSI_TRAN_CONN;
 | 
			
		||||
    uc->m_base.m_base.m_multicast = mcast;
 | 
			
		||||
    uc->m_base.m_base.m_handle_fn = ddsi_udp_conn_handle;
 | 
			
		||||
| 
						 | 
				
			
			@ -252,20 +252,18 @@ static ddsi_tran_conn_t ddsi_udp_create_conn (ddsi_tran_factory_t fact, uint32_t
 | 
			
		|||
    uc->m_base.m_disable_multiplexing_fn = ddsi_udp_disable_multiplexing;
 | 
			
		||||
    uc->m_base.m_locator_fn = ddsi_udp_conn_locator;
 | 
			
		||||
 | 
			
		||||
    DDS_TRACE
 | 
			
		||||
    (
 | 
			
		||||
      "ddsi_udp_create_conn %s socket %"PRIdSOCK" port %"PRIu32"\n",
 | 
			
		||||
      mcast ? "multicast" : "unicast",
 | 
			
		||||
      uc->m_sock,
 | 
			
		||||
      uc->m_base.m_base.m_port
 | 
			
		||||
    );
 | 
			
		||||
    DDS_CTRACE (&fact->gv->logconfig,
 | 
			
		||||
                "ddsi_udp_create_conn %s socket %"PRIdSOCK" port %"PRIu32"\n",
 | 
			
		||||
                mcast ? "multicast" : "unicast",
 | 
			
		||||
                uc->m_sock,
 | 
			
		||||
                uc->m_base.m_base.m_port);
 | 
			
		||||
#ifdef DDSI_INCLUDE_NETWORK_CHANNELS
 | 
			
		||||
    if ((uc->m_diffserv != 0) && (fact->m_kind == NN_LOCATOR_KIND_UDPv4))
 | 
			
		||||
    {
 | 
			
		||||
      dds_return_t rc;
 | 
			
		||||
      rc = ddsrt_setsockopt(sock, IPPROTO_IP, IP_TOS, (char *)&uc->m_diffserv, sizeof(uc->m_diffserv));
 | 
			
		||||
      if (rc != DDS_RETCODE_OK)
 | 
			
		||||
        DDS_ERROR("ddsi_udp_create_conn: set diffserv retcode %"PRId32"\n", rc);
 | 
			
		||||
        DDS_CERROR (fact->gv->logconfig, "ddsi_udp_create_conn: set diffserv retcode %"PRId32"\n", rc);
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
  }
 | 
			
		||||
| 
						 | 
				
			
			@ -273,12 +271,7 @@ static ddsi_tran_conn_t ddsi_udp_create_conn (ddsi_tran_factory_t fact, uint32_t
 | 
			
		|||
  {
 | 
			
		||||
    if (fact->gv->config.participantIndex != PARTICIPANT_INDEX_AUTO)
 | 
			
		||||
    {
 | 
			
		||||
      DDS_ERROR
 | 
			
		||||
      (
 | 
			
		||||
        "UDP make_socket failed for %s port %"PRIu32"\n",
 | 
			
		||||
        mcast ? "multicast" : "unicast",
 | 
			
		||||
        port
 | 
			
		||||
      );
 | 
			
		||||
      DDS_CERROR (&fact->gv->logconfig, "UDP make_socket failed for %s port %"PRIu32"\n", mcast ? "multicast" : "unicast", port);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -374,13 +367,11 @@ static int ddsi_udp_leave_mc (ddsi_tran_conn_t conn, const nn_locator_t *srcloc,
 | 
			
		|||
static void ddsi_udp_release_conn (ddsi_tran_conn_t conn)
 | 
			
		||||
{
 | 
			
		||||
  ddsi_udp_conn_t uc = (ddsi_udp_conn_t) conn;
 | 
			
		||||
  DDS_TRACE
 | 
			
		||||
  (
 | 
			
		||||
    "ddsi_udp_release_conn %s socket %"PRIdSOCK" port %"PRIu32"\n",
 | 
			
		||||
    conn->m_base.m_multicast ? "multicast" : "unicast",
 | 
			
		||||
    uc->m_sock,
 | 
			
		||||
    uc->m_base.m_base.m_port
 | 
			
		||||
  );
 | 
			
		||||
  DDS_CTRACE (&conn->m_base.gv->logconfig,
 | 
			
		||||
              "ddsi_udp_release_conn %s socket %"PRIdSOCK" port %"PRIu32"\n",
 | 
			
		||||
              conn->m_base.m_multicast ? "multicast" : "unicast",
 | 
			
		||||
              uc->m_sock,
 | 
			
		||||
              uc->m_base.m_base.m_port);
 | 
			
		||||
  ddsrt_close (uc->m_sock);
 | 
			
		||||
#if defined _WIN32 && !defined WINCE
 | 
			
		||||
  WSACloseEvent(uc->m_sockEvent);
 | 
			
		||||
| 
						 | 
				
			
			@ -471,7 +462,7 @@ static char *ddsi_udp_locator_to_string (ddsi_tran_factory_t tran, char *dst, si
 | 
			
		|||
 | 
			
		||||
static void ddsi_udp_fini (ddsi_tran_factory_t fact)
 | 
			
		||||
{
 | 
			
		||||
  DDS_LOG (DDS_LC_CONFIG, "udp finalized\n");
 | 
			
		||||
  DDS_CLOG (DDS_LC_CONFIG, &fact->gv->logconfig, "udp finalized\n");
 | 
			
		||||
  ddsrt_free (fact);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -508,6 +499,6 @@ int ddsi_udp_init (struct q_globals *gv)
 | 
			
		|||
#endif
 | 
			
		||||
 | 
			
		||||
  ddsi_factory_add (gv, fact);
 | 
			
		||||
  DDS_LOG(DDS_LC_CONFIG, "udp initialized\n");
 | 
			
		||||
  GVLOG (DDS_LC_CONFIG, "udp initialized\n");
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -54,19 +54,19 @@ static int add_addresses_to_addrset_1 (const struct q_globals *gv, struct addrse
 | 
			
		|||
    case AFSR_OK:
 | 
			
		||||
      break;
 | 
			
		||||
    case AFSR_INVALID:
 | 
			
		||||
      DDS_ERROR("%s: %s: not a valid address\n", msgtag, ip);
 | 
			
		||||
      GVERROR ("%s: %s: not a valid address\n", msgtag, ip);
 | 
			
		||||
      return -1;
 | 
			
		||||
    case AFSR_UNKNOWN:
 | 
			
		||||
      DDS_ERROR("%s: %s: unknown address\n", msgtag, ip);
 | 
			
		||||
      GVERROR ("%s: %s: unknown address\n", msgtag, ip);
 | 
			
		||||
      return -1;
 | 
			
		||||
    case AFSR_MISMATCH:
 | 
			
		||||
      DDS_ERROR("%s: %s: address family mismatch\n", msgtag, ip);
 | 
			
		||||
      GVERROR ("%s: %s: address family mismatch\n", msgtag, ip);
 | 
			
		||||
      return -1;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (req_mc && !ddsi_is_mcaddr (gv, &loc))
 | 
			
		||||
  {
 | 
			
		||||
    DDS_ERROR ("%s: %s: not a multicast address\n", msgtag, ip);
 | 
			
		||||
    GVERROR ("%s: %s: not a multicast address\n", msgtag, ip);
 | 
			
		||||
    return -1;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -86,46 +86,48 @@ static int add_addresses_to_addrset_1 (const struct q_globals *gv, struct addrse
 | 
			
		|||
  }
 | 
			
		||||
  else
 | 
			
		||||
  {
 | 
			
		||||
    DDS_ERROR("%s: %s,%d,%d,%d: IPv4 multicast address generator invalid or out of place\n",
 | 
			
		||||
              msgtag, ip, mcgen_base, mcgen_count, mcgen_idx);
 | 
			
		||||
    GVERROR ("%s: %s,%d,%d,%d: IPv4 multicast address generator invalid or out of place\n",
 | 
			
		||||
             msgtag, ip, mcgen_base, mcgen_count, mcgen_idx);
 | 
			
		||||
    return -1;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (port_mode >= 0)
 | 
			
		||||
  {
 | 
			
		||||
    loc.port = (unsigned) port_mode;
 | 
			
		||||
    DDS_LOG(DDS_LC_CONFIG, "%s: add %s", msgtag, ddsi_locator_to_string(gv, buf, sizeof(buf), &loc));
 | 
			
		||||
    GVLOG (DDS_LC_CONFIG, "%s: add %s", msgtag, ddsi_locator_to_string(gv, buf, sizeof(buf), &loc));
 | 
			
		||||
    add_to_addrset (gv, as, &loc);
 | 
			
		||||
  }
 | 
			
		||||
  else
 | 
			
		||||
  {
 | 
			
		||||
    DDS_LOG(DDS_LC_CONFIG, "%s: add ", msgtag);
 | 
			
		||||
    GVLOG (DDS_LC_CONFIG, "%s: add ", msgtag);
 | 
			
		||||
    if (!ddsi_is_mcaddr (gv, &loc))
 | 
			
		||||
    {
 | 
			
		||||
      int i;
 | 
			
		||||
      for (i = 0; i <= gv->config.maxAutoParticipantIndex; i++)
 | 
			
		||||
      assert (gv->config.maxAutoParticipantIndex >= 0);
 | 
			
		||||
      for (uint32_t i = 0; i <= (uint32_t) gv->config.maxAutoParticipantIndex; i++)
 | 
			
		||||
      {
 | 
			
		||||
        int port = gv->config.port_base + gv->config.port_dg * gv->config.domainId.value + i * gv->config.port_pg + gv->config.port_d1;
 | 
			
		||||
        uint32_t port = gv->config.port_base + gv->config.port_dg * gv->config.domainId.value + i * gv->config.port_pg + gv->config.port_d1;
 | 
			
		||||
        loc.port = (unsigned) port;
 | 
			
		||||
        if (i == 0)
 | 
			
		||||
          DDS_LOG(DDS_LC_CONFIG, "%s", ddsi_locator_to_string(gv, buf, sizeof(buf), &loc));
 | 
			
		||||
          GVLOG (DDS_LC_CONFIG, "%s", ddsi_locator_to_string(gv, buf, sizeof(buf), &loc));
 | 
			
		||||
        else
 | 
			
		||||
          DDS_LOG(DDS_LC_CONFIG, ", :%d", port);
 | 
			
		||||
          GVLOG (DDS_LC_CONFIG, ", :%"PRIu32, port);
 | 
			
		||||
        add_to_addrset (gv, as, &loc);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
      int port = port_mode;
 | 
			
		||||
      if (port == -1)
 | 
			
		||||
      uint32_t port;
 | 
			
		||||
      if (port_mode == -1)
 | 
			
		||||
        port = gv->config.port_base + gv->config.port_dg * gv->config.domainId.value + gv->config.port_d0;
 | 
			
		||||
      else
 | 
			
		||||
        port = (uint32_t) port_mode;
 | 
			
		||||
      loc.port = (unsigned) port;
 | 
			
		||||
      DDS_LOG(DDS_LC_CONFIG, "%s", ddsi_locator_to_string(gv, buf, sizeof(buf), &loc));
 | 
			
		||||
      GVLOG (DDS_LC_CONFIG, "%s", ddsi_locator_to_string(gv, buf, sizeof(buf), &loc));
 | 
			
		||||
      add_to_addrset (gv, as, &loc);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  DDS_LOG(DDS_LC_CONFIG, "\n");
 | 
			
		||||
  GVLOG (DDS_LC_CONFIG, "\n");
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -173,7 +175,7 @@ int add_addresses_to_addrset (const struct q_globals *gv, struct addrset *as, co
 | 
			
		|||
      if (add_addresses_to_addrset_1 (gv, as, ip, port, msgtag, req_mc, mcgen_base, mcgen_count, mcgen_idx) < 0)
 | 
			
		||||
        goto error;
 | 
			
		||||
    } else {
 | 
			
		||||
      DDS_ERROR("%s: %s: port %d invalid\n", msgtag, a, port);
 | 
			
		||||
      GVERROR ("%s: %s: port %d invalid\n", msgtag, a, port);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  retval = 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -555,19 +557,20 @@ struct log_addrset_helper_arg
 | 
			
		|||
static void log_addrset_helper (const nn_locator_t *n, void *varg)
 | 
			
		||||
{
 | 
			
		||||
  const struct log_addrset_helper_arg *arg = varg;
 | 
			
		||||
  const struct q_globals *gv = arg->gv;
 | 
			
		||||
  char buf[DDSI_LOCSTRLEN];
 | 
			
		||||
  if (dds_get_log_mask() & arg->tf)
 | 
			
		||||
    DDS_LOG(arg->tf, " %s", ddsi_locator_to_string(arg->gv, buf, sizeof(buf), n));
 | 
			
		||||
  if (gv->logconfig.c.mask & arg->tf)
 | 
			
		||||
    GVLOG (arg->tf, " %s", ddsi_locator_to_string (gv, buf, sizeof(buf), n));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void nn_log_addrset (struct q_globals *gv, uint32_t tf, const char *prefix, const struct addrset *as)
 | 
			
		||||
{
 | 
			
		||||
  if (dds_get_log_mask() & tf)
 | 
			
		||||
  if (gv->logconfig.c.mask & tf)
 | 
			
		||||
  {
 | 
			
		||||
    struct log_addrset_helper_arg arg;
 | 
			
		||||
    arg.tf = tf;
 | 
			
		||||
    arg.gv = gv;
 | 
			
		||||
    DDS_LOG(tf, "%s", prefix);
 | 
			
		||||
    GVLOG (tf, "%s", prefix);
 | 
			
		||||
    addrset_forall ((struct addrset *) as, log_addrset_helper, &arg); /* drop const, we know it is */
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -92,15 +92,13 @@ enum implicit_toplevel {
 | 
			
		|||
struct cfgst {
 | 
			
		||||
  ddsrt_avl_tree_t found;
 | 
			
		||||
  struct config *cfg;
 | 
			
		||||
  uint32_t domid;
 | 
			
		||||
  const struct ddsrt_log_cfg *logcfg; /* for LOG_LC_CONFIG */
 | 
			
		||||
  /* error flag set so that we can continue parsing for some errors and still fail properly */
 | 
			
		||||
  int error;
 | 
			
		||||
 | 
			
		||||
  enum implicit_toplevel implicit_toplevel;
 | 
			
		||||
 | 
			
		||||
  /* We want the tracing/verbosity settings to be fixed while parsing
 | 
			
		||||
     the configuration, so we update this variable instead. */
 | 
			
		||||
  uint32_t enabled_logcats;
 | 
			
		||||
 | 
			
		||||
  /* current input, mask with 1 bit set */
 | 
			
		||||
  uint32_t source;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -624,19 +622,19 @@ static const struct cfgelem sizing_cfgelems[] = {
 | 
			
		|||
};
 | 
			
		||||
 | 
			
		||||
static const struct cfgelem discovery_ports_cfgelems[] = {
 | 
			
		||||
  { LEAF("Base"), 1, "7400", ABSOFF(port_base), 0, uf_port, 0, pf_int,
 | 
			
		||||
  { LEAF("Base"), 1, "7400", ABSOFF(port_base), 0, uf_port, 0, pf_uint,
 | 
			
		||||
    BLURB("<p>This element specifies the base port number (refer to the DDSI 2.1 specification, section 9.6.1, constant PB).</p>") },
 | 
			
		||||
  { LEAF("DomainGain"), 1, "250", ABSOFF(port_dg), 0, uf_int, 0, pf_int,
 | 
			
		||||
  { LEAF("DomainGain"), 1, "250", ABSOFF(port_dg), 0, uf_uint, 0, pf_uint,
 | 
			
		||||
    BLURB("<p>This element specifies the domain gain, relating domain ids to sets of port numbers (refer to the DDSI 2.1 specification, section 9.6.1, constant DG).</p>") },
 | 
			
		||||
  { LEAF("ParticipantGain"), 1, "2", ABSOFF(port_pg), 0, uf_int, 0, pf_int,
 | 
			
		||||
  { LEAF("ParticipantGain"), 1, "2", ABSOFF(port_pg), 0, uf_uint, 0, pf_uint,
 | 
			
		||||
    BLURB("<p>This element specifies the participant gain, relating p0, articipant index to sets of port numbers (refer to the DDSI 2.1 specification, section 9.6.1, constant PG).</p>") },
 | 
			
		||||
  { LEAF("MulticastMetaOffset"), 1, "0", ABSOFF(port_d0), 0, uf_int, 0, pf_int,
 | 
			
		||||
  { LEAF("MulticastMetaOffset"), 1, "0", ABSOFF(port_d0), 0, uf_uint, 0, pf_uint,
 | 
			
		||||
    BLURB("<p>This element specifies the port number for multicast meta traffic (refer to the DDSI 2.1 specification, section 9.6.1, constant d0).</p>") },
 | 
			
		||||
  { LEAF("UnicastMetaOffset"), 1, "10", ABSOFF(port_d1), 0, uf_int, 0, pf_int,
 | 
			
		||||
  { LEAF("UnicastMetaOffset"), 1, "10", ABSOFF(port_d1), 0, uf_uint, 0, pf_uint,
 | 
			
		||||
    BLURB("<p>This element specifies the port number for unicast meta traffic (refer to the DDSI 2.1 specification, section 9.6.1, constant d1).</p>") },
 | 
			
		||||
  { LEAF("MulticastDataOffset"), 1, "1", ABSOFF(port_d2), 0, uf_int, 0, pf_int,
 | 
			
		||||
  { LEAF("MulticastDataOffset"), 1, "1", ABSOFF(port_d2), 0, uf_uint, 0, pf_uint,
 | 
			
		||||
    BLURB("<p>This element specifies the port number for multicast meta traffic (refer to the DDSI 2.1 specification, section 9.6.1, constant d2).</p>") },
 | 
			
		||||
  { LEAF("UnicastDataOffset"), 1, "11", ABSOFF(port_d3), 0, uf_int, 0, pf_int,
 | 
			
		||||
  { LEAF("UnicastDataOffset"), 1, "11", ABSOFF(port_d3), 0, uf_uint, 0, pf_uint,
 | 
			
		||||
    BLURB("<p>This element specifies the port number for unicast meta traffic (refer to the DDSI 2.1 specification, section 9.6.1, constant d3).</p>") },
 | 
			
		||||
  END_MARKER
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			@ -1045,21 +1043,10 @@ static size_t cfg_note (struct cfgst *cfgst, uint32_t cat, size_t bsz, const cha
 | 
			
		|||
  }
 | 
			
		||||
 | 
			
		||||
  cfg_note_snprintf (&bb, "%s", suffix);
 | 
			
		||||
  switch (cat)
 | 
			
		||||
  {
 | 
			
		||||
    case DDS_LC_CONFIG:
 | 
			
		||||
      DDS_LOG (cat, "%s\n", bb.buf);
 | 
			
		||||
      break;
 | 
			
		||||
    case DDS_LC_WARNING:
 | 
			
		||||
      DDS_WARNING ("%s\n", bb.buf);
 | 
			
		||||
      break;
 | 
			
		||||
    case DDS_LC_ERROR:
 | 
			
		||||
      DDS_ERROR ("%s\n", bb.buf);
 | 
			
		||||
      break;
 | 
			
		||||
    default:
 | 
			
		||||
      DDS_FATAL ("cfg_note unhandled category %u for message %s\n", (unsigned) cat, bb.buf);
 | 
			
		||||
      break;
 | 
			
		||||
  }
 | 
			
		||||
  if (cfgst->logcfg)
 | 
			
		||||
    DDS_CLOG (cat, cfgst->logcfg, "%s\n", bb.buf);
 | 
			
		||||
  else
 | 
			
		||||
    DDS_ILOG (cat, cfgst->domid, "%s\n", bb.buf);
 | 
			
		||||
 | 
			
		||||
  ddsrt_free (bb.buf);
 | 
			
		||||
  return 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -1468,7 +1455,7 @@ static const uint32_t logcat_codes[] = {
 | 
			
		|||
 | 
			
		||||
static int uf_logcat (struct cfgst *cfgst, UNUSED_ARG (void *parent), UNUSED_ARG (struct cfgelem const * const cfgelem), UNUSED_ARG (int first), const char *value)
 | 
			
		||||
{
 | 
			
		||||
  return do_uint32_bitset (cfgst, &cfgst->enabled_logcats, logcat_names, logcat_codes, value);
 | 
			
		||||
  return do_uint32_bitset (cfgst, &cfgst->cfg->enabled_logcats, logcat_names, logcat_codes, value);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int uf_verbosity (struct cfgst *cfgst, UNUSED_ARG (void *parent), UNUSED_ARG (struct cfgelem const * const cfgelem), UNUSED_ARG (int first), const char *value)
 | 
			
		||||
| 
						 | 
				
			
			@ -1484,7 +1471,7 @@ static int uf_verbosity (struct cfgst *cfgst, UNUSED_ARG (void *parent), UNUSED_
 | 
			
		|||
  if (idx < 0)
 | 
			
		||||
    return cfg_error (cfgst, "'%s': undefined value", value);
 | 
			
		||||
  for (int i = (int) (sizeof (vs) / sizeof (*vs)) - 1; i >= idx; i--)
 | 
			
		||||
    cfgst->enabled_logcats |= lc[i];
 | 
			
		||||
    cfgst->cfg->enabled_logcats |= lc[i];
 | 
			
		||||
  return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1866,11 +1853,6 @@ static void pf_int (struct cfgst *cfgst, void *parent, struct cfgelem const * co
 | 
			
		|||
  cfg_logelem (cfgst, sources, "%d", *p);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int uf_port(struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, int first, const char *value)
 | 
			
		||||
{
 | 
			
		||||
  return uf_int_min_max(cfgst, parent, cfgelem, first, value, 1, 65535);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int uf_dyn_port(struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, int first, const char *value)
 | 
			
		||||
{
 | 
			
		||||
  return uf_int_min_max(cfgst, parent, cfgelem, first, value, -1, 65535);
 | 
			
		||||
| 
						 | 
				
			
			@ -1905,6 +1887,17 @@ static void pf_uint (struct cfgst *cfgst, void *parent, struct cfgelem const * c
 | 
			
		|||
  cfg_logelem (cfgst, sources, "%u", *p);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int uf_port(struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, int first, const char *value)
 | 
			
		||||
{
 | 
			
		||||
  int *elem = cfg_address (cfgst, parent, cfgelem);
 | 
			
		||||
  if (!uf_uint (cfgst, parent, cfgelem, first, value))
 | 
			
		||||
    return 0;
 | 
			
		||||
  else if (*elem < 1 || *elem > 65535)
 | 
			
		||||
    return cfg_error (cfgst, "%s: out of range", value);
 | 
			
		||||
  else
 | 
			
		||||
    return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int uf_duration_gen (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, const char *value, int64_t def_mult, int64_t min_ns, int64_t max_ns)
 | 
			
		||||
{
 | 
			
		||||
  return uf_natint64_unit (cfgst, cfg_address (cfgst, parent, cfgelem), value, unittab_duration, def_mult, min_ns, max_ns);
 | 
			
		||||
| 
						 | 
				
			
			@ -1953,28 +1946,28 @@ static void pf_duration (struct cfgst *cfgst, void *parent, struct cfgelem const
 | 
			
		|||
static int uf_domainId (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, UNUSED_ARG (int first), const char *value)
 | 
			
		||||
{
 | 
			
		||||
  DDSRT_WARNING_MSVC_OFF(4996);
 | 
			
		||||
  struct config_maybe_int32 * const elem = cfg_address (cfgst, parent, cfgelem);
 | 
			
		||||
  struct config_maybe_uint32 * const elem = cfg_address (cfgst, parent, cfgelem);
 | 
			
		||||
  int pos;
 | 
			
		||||
  if (ddsrt_strcasecmp (value, "any") == 0) {
 | 
			
		||||
    elem->isdefault = 1;
 | 
			
		||||
    elem->value = 0;
 | 
			
		||||
    return 1;
 | 
			
		||||
  } else if (sscanf (value, "%"SCNd32"%n", &elem->value, &pos) == 1 && value[pos] == 0 && elem->value >= 0 && elem->value <= 230) {
 | 
			
		||||
  } else if (sscanf (value, "%"SCNu32"%n", &elem->value, &pos) == 1 && value[pos] == 0 && elem->value != (uint32_t) 0xffffffff) {
 | 
			
		||||
    elem->isdefault = 0;
 | 
			
		||||
    return 1;
 | 
			
		||||
  } else {
 | 
			
		||||
    return cfg_error (cfgst, "'%s': neither 'any' nor a decimal integer in 0 .. 230\n", value);
 | 
			
		||||
    return cfg_error (cfgst, "'%s': neither 'any' nor a less than 2**32-1\n", value);
 | 
			
		||||
  }
 | 
			
		||||
  DDSRT_WARNING_MSVC_ON(4996);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void pf_domainId(struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, uint32_t sources)
 | 
			
		||||
{
 | 
			
		||||
  struct config_maybe_int32 const * const p = cfg_address (cfgst, parent, cfgelem);
 | 
			
		||||
  struct config_maybe_uint32 const * const p = cfg_address (cfgst, parent, cfgelem);
 | 
			
		||||
  if (p->isdefault)
 | 
			
		||||
    cfg_logelem (cfgst, sources, "any (%d)", p->value);
 | 
			
		||||
    cfg_logelem (cfgst, sources, "any (%"PRIu32")", p->value);
 | 
			
		||||
  else
 | 
			
		||||
    cfg_logelem (cfgst, sources, "%d", p->value);
 | 
			
		||||
    cfg_logelem (cfgst, sources, "%"PRIu32, p->value);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int uf_participantIndex (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, int first, const char *value)
 | 
			
		||||
| 
						 | 
				
			
			@ -2361,7 +2354,7 @@ static int proc_elem_open (void *varg, UNUSED_ARG (uintptr_t parentinfo), UNUSED
 | 
			
		|||
static int proc_update_cfgelem (struct cfgst * cfgst, const struct cfgelem *ce, const char *value, bool isattr)
 | 
			
		||||
{
 | 
			
		||||
  void *parent = cfgst_parent (cfgst);
 | 
			
		||||
  char *xvalue = ddsrt_expand_envvars (value);
 | 
			
		||||
  char *xvalue = ddsrt_expand_envvars (value, cfgst->domid);
 | 
			
		||||
  int ok;
 | 
			
		||||
  cfgst_push (cfgst, isattr, isattr ? ce : NULL, parent);
 | 
			
		||||
  ok = do_update (cfgst, ce->update, parent, ce, xvalue, cfgst->source);
 | 
			
		||||
| 
						 | 
				
			
			@ -2463,7 +2456,7 @@ static int sort_channels_cmp (const void *va, const void *vb)
 | 
			
		|||
  return ((*a)->priority == (*b)->priority) ? 0 : ((*a)->priority < (*b)->priority) ? -1 : 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int sort_channels_check_nodups (struct config *cfg)
 | 
			
		||||
static int sort_channels_check_nodups (struct config *cfg, uint32_t domid)
 | 
			
		||||
{
 | 
			
		||||
  /* Selecting a channel is much easier & more elegant if the channels
 | 
			
		||||
     are sorted on descending priority.  While we do retain the list
 | 
			
		||||
| 
						 | 
				
			
			@ -2488,7 +2481,7 @@ static int sort_channels_check_nodups (struct config *cfg)
 | 
			
		|||
  result = 0;
 | 
			
		||||
  for (i = 0; i < n - 1; i++) {
 | 
			
		||||
    if (ary[i]->priority == ary[i + 1]->priority) {
 | 
			
		||||
      DDS_ERROR("config: duplicate channel definition for priority %u: channels %s and %s\n",
 | 
			
		||||
      DDS_ILOG (DDS_LC_ERROR, domid, "config: duplicate channel definition for priority %u: channels %s and %s\n",
 | 
			
		||||
                ary[i]->priority, ary[i]->name, ary[i + 1]->name);
 | 
			
		||||
      result = ERR_ENTITY_EXISTS;
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -2508,7 +2501,7 @@ static int sort_channels_check_nodups (struct config *cfg)
 | 
			
		|||
}
 | 
			
		||||
#endif /* DDSI_INCLUDE_NETWORK_CHANNELS */
 | 
			
		||||
 | 
			
		||||
static FILE *config_open_file (char *tok, char **cursor)
 | 
			
		||||
static FILE *config_open_file (char *tok, char **cursor, uint32_t domid)
 | 
			
		||||
{
 | 
			
		||||
  assert (*tok && !(isspace ((unsigned char) *tok) || *tok == ','));
 | 
			
		||||
  FILE *fp;
 | 
			
		||||
| 
						 | 
				
			
			@ -2525,7 +2518,7 @@ static FILE *config_open_file (char *tok, char **cursor)
 | 
			
		|||
  {
 | 
			
		||||
    if (strncmp (tok, "file://", 7) != 0 || (fp = fopen (tok + 7, "r")) == NULL)
 | 
			
		||||
    {
 | 
			
		||||
      DDS_ERROR ("can't open configuration file %s\n", tok);
 | 
			
		||||
      DDS_ILOG (DDS_LC_ERROR, domid, "can't open configuration file %s\n", tok);
 | 
			
		||||
      return NULL;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
| 
						 | 
				
			
			@ -2533,7 +2526,7 @@ static FILE *config_open_file (char *tok, char **cursor)
 | 
			
		|||
  return fp;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct cfgst *config_init (const char *configfile, struct config *cfg)
 | 
			
		||||
struct cfgst *config_init (const char *configfile, struct config *cfg, uint32_t domid)
 | 
			
		||||
{
 | 
			
		||||
  int ok = 1;
 | 
			
		||||
  struct cfgst *cfgst;
 | 
			
		||||
| 
						 | 
				
			
			@ -2546,11 +2539,8 @@ struct cfgst *config_init (const char *configfile, struct config *cfg)
 | 
			
		|||
  cfgst->cfg = cfg;
 | 
			
		||||
  cfgst->error = 0;
 | 
			
		||||
  cfgst->source = 0;
 | 
			
		||||
  cfgst->enabled_logcats = 0;
 | 
			
		||||
 | 
			
		||||
  /* Initial logging configuration: configuration errors and warnings are dumped to stderr */
 | 
			
		||||
  cfgst->cfg->tracingOutputFile = stderr;
 | 
			
		||||
  cfgst->cfg->enabled_logcats = DDS_LC_ERROR | DDS_LC_WARNING;
 | 
			
		||||
  cfgst->logcfg = NULL;
 | 
			
		||||
  cfgst->domid = domid;
 | 
			
		||||
 | 
			
		||||
  /* eventually, we domainId.value will be the real domain id selected, even if it was configured
 | 
			
		||||
     to the default of "any" and has "isdefault" set; initializing it to the default-default
 | 
			
		||||
| 
						 | 
				
			
			@ -2584,7 +2574,7 @@ struct cfgst *config_init (const char *configfile, struct config *cfg)
 | 
			
		|||
        ddsrt_xmlp_set_options (qx, DDSRT_XMLP_ANONYMOUS_CLOSE_TAG | DDSRT_XMLP_MISSING_CLOSE_AS_EOF);
 | 
			
		||||
        fp = NULL;
 | 
			
		||||
      }
 | 
			
		||||
      else if ((fp = config_open_file (tok, &cursor)) == NULL)
 | 
			
		||||
      else if ((fp = config_open_file (tok, &cursor, domid)) == NULL)
 | 
			
		||||
      {
 | 
			
		||||
        ddsrt_free (copy);
 | 
			
		||||
        goto error;
 | 
			
		||||
| 
						 | 
				
			
			@ -2651,7 +2641,7 @@ struct cfgst *config_init (const char *configfile, struct config *cfg)
 | 
			
		|||
        break;
 | 
			
		||||
    }
 | 
			
		||||
    if (!ok1)
 | 
			
		||||
      DDS_ERROR("config: invalid combination of Transport, IPv6, TCP\n");
 | 
			
		||||
      DDS_ILOG (DDS_LC_ERROR, domid, "config: invalid combination of Transport, IPv6, TCP\n");
 | 
			
		||||
    ok = ok && ok1;
 | 
			
		||||
    cfgst->cfg->compat_use_ipv6 = (cfgst->cfg->transport_selector == TRANS_UDP6 || cfgst->cfg->transport_selector == TRANS_TCP6) ? BOOLDEF_TRUE : BOOLDEF_FALSE;
 | 
			
		||||
    cfgst->cfg->compat_tcp_enable = (cfgst->cfg->transport_selector == TRANS_TCP || cfgst->cfg->transport_selector == TRANS_TCP6) ? BOOLDEF_TRUE : BOOLDEF_FALSE;
 | 
			
		||||
| 
						 | 
				
			
			@ -2678,19 +2668,19 @@ struct cfgst *config_init (const char *configfile, struct config *cfg)
 | 
			
		|||
        case Q_CIPHER_NULL:
 | 
			
		||||
          /* nop */
 | 
			
		||||
          if (s->key && strlen(s->key) > 0)
 | 
			
		||||
            DDS_INFO ("config: DDSI2Service/Security/SecurityProfile[@cipherkey]: %s: cipher key not required\n", s->key);
 | 
			
		||||
            DDS_ILOG (DDS_LC_INFO, domid, "config: DDSI2Service/Security/SecurityProfile[@cipherkey]: %s: cipher key not required\n", s->key);
 | 
			
		||||
          break;
 | 
			
		||||
 | 
			
		||||
        default:
 | 
			
		||||
          /* read the cipherkey if present */
 | 
			
		||||
          if (!s->key || strlen(s->key) == 0)
 | 
			
		||||
          {
 | 
			
		||||
            DDS_ERROR ("config: DDSI2Service/Security/SecurityProfile[@cipherkey]: cipher key missing\n");
 | 
			
		||||
            DDS_ILOG (DDS_LC_ERROR, domid, "config: DDSI2Service/Security/SecurityProfile[@cipherkey]: cipher key missing\n");
 | 
			
		||||
            ok = 0;
 | 
			
		||||
          }
 | 
			
		||||
          else if (q_security_plugin.valid_uri && !(q_security_plugin.valid_uri) (s->cipher, s->key))
 | 
			
		||||
          {
 | 
			
		||||
            DDS_ERROR ("config: DDSI2Service/Security/SecurityProfile[@cipherkey]: %s : incorrect key\n", s->key);
 | 
			
		||||
            DDS_ILOG (DDS_LC_ERROR, domid, "config: DDSI2Service/Security/SecurityProfile[@cipherkey]: %s : incorrect key\n", s->key);
 | 
			
		||||
            ok = 0;
 | 
			
		||||
          }
 | 
			
		||||
      }
 | 
			
		||||
| 
						 | 
				
			
			@ -2722,7 +2712,7 @@ struct cfgst *config_init (const char *configfile, struct config *cfg)
 | 
			
		|||
          p->securityProfile = s;
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
          DDS_ERROR("config: DDSI2Service/Partitioning/NetworkPartitions/NetworkPartition[@securityprofile]: %s: unknown securityprofile\n", p->profileName);
 | 
			
		||||
          DDS_ILOG (DDS_LC_ERROR, domid, "config: DDSI2Service/Partitioning/NetworkPartitions/NetworkPartition[@securityprofile]: %s: unknown securityprofile\n", p->profileName);
 | 
			
		||||
          ok = 0;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
| 
						 | 
				
			
			@ -2751,7 +2741,7 @@ struct cfgst *config_init (const char *configfile, struct config *cfg)
 | 
			
		|||
        m->partition = p;
 | 
			
		||||
      else
 | 
			
		||||
      {
 | 
			
		||||
        DDS_ERROR ("config: DDSI2Service/Partitioning/PartitionMappings/PartitionMapping[@networkpartition]: %s: unknown partition\n", m->networkPartition);
 | 
			
		||||
        DDS_ILOG (DDS_LC_ERROR, domid, "config: DDSI2Service/Partitioning/PartitionMappings/PartitionMapping[@networkpartition]: %s: unknown partition\n", m->networkPartition);
 | 
			
		||||
        ok = 0;
 | 
			
		||||
      }
 | 
			
		||||
      m = m->next;
 | 
			
		||||
| 
						 | 
				
			
			@ -2759,9 +2749,6 @@ struct cfgst *config_init (const char *configfile, struct config *cfg)
 | 
			
		|||
  }
 | 
			
		||||
#endif /* DDSI_INCLUDE_NETWORK_PARTITIONS */
 | 
			
		||||
 | 
			
		||||
  /* Now switch to configured tracing settings */
 | 
			
		||||
  cfgst->cfg->enabled_logcats = cfgst->enabled_logcats;
 | 
			
		||||
 | 
			
		||||
  if (ok)
 | 
			
		||||
  {
 | 
			
		||||
    cfgst->cfg->valid = 1;
 | 
			
		||||
| 
						 | 
				
			
			@ -2775,10 +2762,12 @@ error:
 | 
			
		|||
  return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void config_print_cfgst (struct cfgst *cfgst)
 | 
			
		||||
void config_print_cfgst (struct cfgst *cfgst, const struct ddsrt_log_cfg *logcfg)
 | 
			
		||||
{
 | 
			
		||||
  if (cfgst == NULL)
 | 
			
		||||
    return;
 | 
			
		||||
  assert (cfgst->logcfg == NULL);
 | 
			
		||||
  cfgst->logcfg = logcfg;
 | 
			
		||||
  print_configitems (cfgst, cfgst->cfg, 0, root_cfgelems, 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -197,11 +197,11 @@ int spdp_write (struct participant *pp)
 | 
			
		|||
      return 0;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  DDS_TRACE("spdp_write("PGUIDFMT")\n", PGUID (pp->e.guid));
 | 
			
		||||
  ETRACE (pp, "spdp_write("PGUIDFMT")\n", PGUID (pp->e.guid));
 | 
			
		||||
 | 
			
		||||
  if ((wr = get_builtin_writer (pp, NN_ENTITYID_SPDP_BUILTIN_PARTICIPANT_WRITER)) == NULL)
 | 
			
		||||
  {
 | 
			
		||||
    DDS_TRACE("spdp_write("PGUIDFMT") - builtin participant writer not found\n", PGUID (pp->e.guid));
 | 
			
		||||
    ETRACE (pp, "spdp_write("PGUIDFMT") - builtin participant writer not found\n", PGUID (pp->e.guid));
 | 
			
		||||
    return 0;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -307,7 +307,7 @@ int spdp_write (struct participant *pp)
 | 
			
		|||
    size = strlen(node) + strlen(DDS_VERSION) + strlen(DDS_HOST_NAME) + strlen(DDS_TARGET_NAME) + 4; /* + ///'\0' */
 | 
			
		||||
    ps.prismtech_participant_version_info.internals = ddsrt_malloc(size);
 | 
			
		||||
    (void) snprintf(ps.prismtech_participant_version_info.internals, size, "%s/%s/%s/%s", node, DDS_VERSION, DDS_HOST_NAME, DDS_TARGET_NAME);
 | 
			
		||||
    DDS_TRACE("spdp_write("PGUIDFMT") - internals: %s\n", PGUID (pp->e.guid), ps.prismtech_participant_version_info.internals);
 | 
			
		||||
    ETRACE (pp, "spdp_write("PGUIDFMT") - internals: %s\n", PGUID (pp->e.guid), ps.prismtech_participant_version_info.internals);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /* Participant QoS's insofar as they are set, different from the default, and mapped to the SPDP data, rather than to the PrismTech-specific CMParticipant endpoint.  Currently, that means just USER_DATA. */
 | 
			
		||||
| 
						 | 
				
			
			@ -335,7 +335,7 @@ int spdp_dispose_unregister (struct participant *pp)
 | 
			
		|||
 | 
			
		||||
  if ((wr = get_builtin_writer (pp, NN_ENTITYID_SPDP_BUILTIN_PARTICIPANT_WRITER)) == NULL)
 | 
			
		||||
  {
 | 
			
		||||
    DDS_TRACE("spdp_dispose_unregister("PGUIDFMT") - builtin participant writer not found\n", PGUID (pp->e.guid));
 | 
			
		||||
    ETRACE (pp, "spdp_dispose_unregister("PGUIDFMT") - builtin participant writer not found\n", PGUID (pp->e.guid));
 | 
			
		||||
    return 0;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -396,7 +396,7 @@ static void respond_to_spdp (const struct q_globals *gv, const nn_guid_t *dest_p
 | 
			
		|||
    int64_t delay_max_ms = gv->config.spdp_response_delay_max / 1000000;
 | 
			
		||||
    int64_t delay = (int64_t) delay_norm * delay_max_ms / 1000;
 | 
			
		||||
    nn_mtime_t tsched = add_duration_to_mtime (tnow, delay);
 | 
			
		||||
    DDS_TRACE(" %"PRId64, delay);
 | 
			
		||||
    GVTRACE (" %"PRId64, delay);
 | 
			
		||||
    if (!pp->e.gv->config.unicast_response_to_spdp_messages)
 | 
			
		||||
      /* pp can't reach gc_delete_participant => can safely reschedule */
 | 
			
		||||
      resched_xevent_if_earlier (pp->spdp_xevent, tsched);
 | 
			
		||||
| 
						 | 
				
			
			@ -408,28 +408,29 @@ static void respond_to_spdp (const struct q_globals *gv, const nn_guid_t *dest_p
 | 
			
		|||
 | 
			
		||||
static int handle_SPDP_dead (const struct receiver_state *rst, nn_wctime_t timestamp, const nn_plist_t *datap, unsigned statusinfo)
 | 
			
		||||
{
 | 
			
		||||
  struct q_globals * const gv = rst->gv;
 | 
			
		||||
  nn_guid_t guid;
 | 
			
		||||
 | 
			
		||||
  if (!(dds_get_log_mask() & DDS_LC_DISCOVERY))
 | 
			
		||||
    DDS_LOG(DDS_LC_DISCOVERY, "SPDP ST%x", statusinfo);
 | 
			
		||||
  if (!(gv->logconfig.c.mask & DDS_LC_DISCOVERY))
 | 
			
		||||
    GVLOGDISC ("SPDP ST%x", statusinfo);
 | 
			
		||||
 | 
			
		||||
  if (datap->present & PP_PARTICIPANT_GUID)
 | 
			
		||||
  {
 | 
			
		||||
    guid = datap->participant_guid;
 | 
			
		||||
    DDS_LOG(DDS_LC_DISCOVERY, " %"PRIx32":%"PRIx32":%"PRIx32":%"PRIx32, PGUID (guid));
 | 
			
		||||
    GVLOGDISC (" %"PRIx32":%"PRIx32":%"PRIx32":%"PRIx32, PGUID (guid));
 | 
			
		||||
    assert (guid.entityid.u == NN_ENTITYID_PARTICIPANT);
 | 
			
		||||
    if (delete_proxy_participant_by_guid (rst->gv, &guid, timestamp, 0) < 0)
 | 
			
		||||
    if (delete_proxy_participant_by_guid (gv, &guid, timestamp, 0) < 0)
 | 
			
		||||
    {
 | 
			
		||||
      DDS_LOG(DDS_LC_DISCOVERY, " unknown");
 | 
			
		||||
      GVLOGDISC (" unknown");
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
      DDS_LOG(DDS_LC_DISCOVERY, " delete");
 | 
			
		||||
      GVLOGDISC (" delete");
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  else
 | 
			
		||||
  {
 | 
			
		||||
    DDS_WARNING("data (SPDP, vendor %u.%u): no/invalid payload\n", rst->vendor.id[0], rst->vendor.id[1]);
 | 
			
		||||
    GVWARNING ("data (SPDP, vendor %u.%u): no/invalid payload\n", rst->vendor.id[0], rst->vendor.id[1]);
 | 
			
		||||
  }
 | 
			
		||||
  return 1;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -481,12 +482,12 @@ static void make_participants_dependent_on_ddsi2 (struct q_globals *gv, const nn
 | 
			
		|||
  {
 | 
			
		||||
    if (vendor_is_eclipse_or_opensplice (pp->vendor) && pp->e.guid.prefix.u[0] == ddsi2guid->prefix.u[0] && !pp->is_ddsi2_pp)
 | 
			
		||||
    {
 | 
			
		||||
      DDS_TRACE("proxy participant "PGUIDFMT" depends on ddsi2 "PGUIDFMT, PGUID (pp->e.guid), PGUID (*ddsi2guid));
 | 
			
		||||
      GVTRACE ("proxy participant "PGUIDFMT" depends on ddsi2 "PGUIDFMT, PGUID (pp->e.guid), PGUID (*ddsi2guid));
 | 
			
		||||
      ddsrt_mutex_lock (&pp->e.lock);
 | 
			
		||||
      pp->privileged_pp_guid = *ddsi2guid;
 | 
			
		||||
      ddsrt_mutex_unlock (&pp->e.lock);
 | 
			
		||||
      proxy_participant_reassign_lease (pp, d2pp_lease);
 | 
			
		||||
      DDS_TRACE("\n");
 | 
			
		||||
      GVTRACE ("\n");
 | 
			
		||||
 | 
			
		||||
      if (ephash_lookup_proxy_participant_guid (gv->guid_hash, ddsi2guid) == NULL)
 | 
			
		||||
      {
 | 
			
		||||
| 
						 | 
				
			
			@ -501,13 +502,14 @@ static void make_participants_dependent_on_ddsi2 (struct q_globals *gv, const nn
 | 
			
		|||
 | 
			
		||||
  if (pp != NULL)
 | 
			
		||||
  {
 | 
			
		||||
    DDS_TRACE("make_participants_dependent_on_ddsi2: ddsi2 "PGUIDFMT" is no more, delete "PGUIDFMT"\n", PGUID (*ddsi2guid), PGUID (pp->e.guid));
 | 
			
		||||
    GVTRACE ("make_participants_dependent_on_ddsi2: ddsi2 "PGUIDFMT" is no more, delete "PGUIDFMT"\n", PGUID (*ddsi2guid), PGUID (pp->e.guid));
 | 
			
		||||
    delete_proxy_participant_by_guid (gv, &pp->e.guid, timestamp, 1);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int handle_SPDP_alive (const struct receiver_state *rst, seqno_t seq, nn_wctime_t timestamp, const nn_plist_t *datap)
 | 
			
		||||
{
 | 
			
		||||
  struct q_globals * const gv = rst->gv;
 | 
			
		||||
  const unsigned bes_sedp_announcer_mask =
 | 
			
		||||
    NN_DISC_BUILTIN_ENDPOINT_SUBSCRIPTION_ANNOUNCER |
 | 
			
		||||
    NN_DISC_BUILTIN_ENDPOINT_PUBLICATION_ANNOUNCER;
 | 
			
		||||
| 
						 | 
				
			
			@ -521,7 +523,7 @@ static int handle_SPDP_alive (const struct receiver_state *rst, seqno_t seq, nn_
 | 
			
		|||
 | 
			
		||||
  if (!(datap->present & PP_PARTICIPANT_GUID) || !(datap->present & PP_BUILTIN_ENDPOINT_SET))
 | 
			
		||||
  {
 | 
			
		||||
    DDS_WARNING("data (SPDP, vendor %u.%u): no/invalid payload\n", rst->vendor.id[0], rst->vendor.id[1]);
 | 
			
		||||
    GVWARNING ("data (SPDP, vendor %u.%u): no/invalid payload\n", rst->vendor.id[0], rst->vendor.id[1]);
 | 
			
		||||
    return 1;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -537,10 +539,10 @@ static int handle_SPDP_alive (const struct receiver_state *rst, seqno_t seq, nn_
 | 
			
		|||
         NN_BUILTIN_ENDPOINT_PARTICIPANT_MESSAGE_DATA_WRITER))
 | 
			
		||||
       != (NN_BUILTIN_ENDPOINT_PARTICIPANT_MESSAGE_DATA_READER |
 | 
			
		||||
           NN_BUILTIN_ENDPOINT_PARTICIPANT_MESSAGE_DATA_WRITER)) &&
 | 
			
		||||
      rst->gv->config.assume_rti_has_pmd_endpoints)
 | 
			
		||||
      gv->config.assume_rti_has_pmd_endpoints)
 | 
			
		||||
  {
 | 
			
		||||
    DDS_LOG(DDS_LC_DISCOVERY, "data (SPDP, vendor %u.%u): assuming unadvertised PMD endpoints do exist\n",
 | 
			
		||||
                 rst->vendor.id[0], rst->vendor.id[1]);
 | 
			
		||||
    GVLOGDISC ("data (SPDP, vendor %u.%u): assuming unadvertised PMD endpoints do exist\n",
 | 
			
		||||
             rst->vendor.id[0], rst->vendor.id[1]);
 | 
			
		||||
    builtin_endpoint_set |=
 | 
			
		||||
      NN_BUILTIN_ENDPOINT_PARTICIPANT_MESSAGE_DATA_READER |
 | 
			
		||||
      NN_BUILTIN_ENDPOINT_PARTICIPANT_MESSAGE_DATA_WRITER;
 | 
			
		||||
| 
						 | 
				
			
			@ -554,7 +556,7 @@ static int handle_SPDP_alive (const struct receiver_state *rst, seqno_t seq, nn_
 | 
			
		|||
       but it would cause problems with cases where we would be happy with only
 | 
			
		||||
       (say) CM participant. Have to do a backwards-compatible fix because it has
 | 
			
		||||
       already been released with the flags all aliased to bits 0 and 1 ... */
 | 
			
		||||
      DDS_LOG(DDS_LC_DISCOVERY, " (ptbes_fixed_0 %x)", prismtech_builtin_endpoint_set);
 | 
			
		||||
      GVLOGDISC (" (ptbes_fixed_0 %x)", prismtech_builtin_endpoint_set);
 | 
			
		||||
      if (prismtech_builtin_endpoint_set & NN_DISC_BUILTIN_ENDPOINT_CM_PARTICIPANT_READER)
 | 
			
		||||
        prismtech_builtin_endpoint_set |= NN_DISC_BUILTIN_ENDPOINT_CM_PUBLISHER_READER | NN_DISC_BUILTIN_ENDPOINT_CM_SUBSCRIBER_READER;
 | 
			
		||||
      if (prismtech_builtin_endpoint_set & NN_DISC_BUILTIN_ENDPOINT_CM_PARTICIPANT_WRITER)
 | 
			
		||||
| 
						 | 
				
			
			@ -567,38 +569,38 @@ static int handle_SPDP_alive (const struct receiver_state *rst, seqno_t seq, nn_
 | 
			
		|||
     consequently the looped back packet may appear to be from an
 | 
			
		||||
     unknown participant.  So we handle that, too. */
 | 
			
		||||
 | 
			
		||||
  if (is_deleted_participant_guid (rst->gv->deleted_participants, &datap->participant_guid, DPG_REMOTE))
 | 
			
		||||
  if (is_deleted_participant_guid (gv->deleted_participants, &datap->participant_guid, DPG_REMOTE))
 | 
			
		||||
  {
 | 
			
		||||
    DDS_LOG(DDS_LC_TRACE, "SPDP ST0 "PGUIDFMT" (recently deleted)", PGUID (datap->participant_guid));
 | 
			
		||||
    RSTTRACE ("SPDP ST0 "PGUIDFMT" (recently deleted)", PGUID (datap->participant_guid));
 | 
			
		||||
    return 1;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  {
 | 
			
		||||
    int islocal = 0;
 | 
			
		||||
    if (ephash_lookup_participant_guid (rst->gv->guid_hash, &datap->participant_guid))
 | 
			
		||||
    if (ephash_lookup_participant_guid (gv->guid_hash, &datap->participant_guid))
 | 
			
		||||
      islocal = 1;
 | 
			
		||||
    if (islocal)
 | 
			
		||||
    {
 | 
			
		||||
      DDS_LOG(DDS_LC_TRACE, "SPDP ST0 "PGUIDFMT" (local %d)", PGUID (datap->participant_guid), islocal);
 | 
			
		||||
      RSTTRACE ("SPDP ST0 "PGUIDFMT" (local %d)", PGUID (datap->participant_guid), islocal);
 | 
			
		||||
      return 0;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if ((proxypp = ephash_lookup_proxy_participant_guid (rst->gv->guid_hash, &datap->participant_guid)) != NULL)
 | 
			
		||||
  if ((proxypp = ephash_lookup_proxy_participant_guid (gv->guid_hash, &datap->participant_guid)) != NULL)
 | 
			
		||||
  {
 | 
			
		||||
    /* SPDP processing is so different from normal processing that we
 | 
			
		||||
       are even skipping the automatic lease renewal.  Therefore do it
 | 
			
		||||
       regardless of
 | 
			
		||||
       gv.config.arrival_of_data_asserts_pp_and_ep_liveliness. */
 | 
			
		||||
    DDS_LOG(DDS_LC_TRACE, "SPDP ST0 "PGUIDFMT" (known)", PGUID (datap->participant_guid));
 | 
			
		||||
    RSTTRACE ("SPDP ST0 "PGUIDFMT" (known)", PGUID (datap->participant_guid));
 | 
			
		||||
    lease_renew (ddsrt_atomic_ldvoidp (&proxypp->lease), now_et ());
 | 
			
		||||
    ddsrt_mutex_lock (&proxypp->e.lock);
 | 
			
		||||
    if (proxypp->implicitly_created || seq > proxypp->seq)
 | 
			
		||||
    {
 | 
			
		||||
      if (proxypp->implicitly_created)
 | 
			
		||||
        DDS_LOG(DDS_LC_DISCOVERY, " (NEW was-implicitly-created)");
 | 
			
		||||
        GVLOGDISC (" (NEW was-implicitly-created)");
 | 
			
		||||
      else
 | 
			
		||||
        DDS_LOG(DDS_LC_DISCOVERY, " (update)");
 | 
			
		||||
        GVLOGDISC (" (update)");
 | 
			
		||||
      proxypp->implicitly_created = 0;
 | 
			
		||||
      update_proxy_participant_plist_locked (proxypp, seq, datap, UPD_PROXYPP_SPDP, timestamp);
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -606,7 +608,7 @@ static int handle_SPDP_alive (const struct receiver_state *rst, seqno_t seq, nn_
 | 
			
		|||
    return 0;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  DDS_LOG(DDS_LC_DISCOVERY, "SPDP ST0 "PGUIDFMT" bes %x ptbes %x NEW", PGUID (datap->participant_guid), builtin_endpoint_set, prismtech_builtin_endpoint_set);
 | 
			
		||||
  GVLOGDISC ("SPDP ST0 "PGUIDFMT" bes %x ptbes %x NEW", PGUID (datap->participant_guid), builtin_endpoint_set, prismtech_builtin_endpoint_set);
 | 
			
		||||
 | 
			
		||||
  if (datap->present & PP_PARTICIPANT_LEASE_DURATION)
 | 
			
		||||
  {
 | 
			
		||||
| 
						 | 
				
			
			@ -614,7 +616,7 @@ static int handle_SPDP_alive (const struct receiver_state *rst, seqno_t seq, nn_
 | 
			
		|||
  }
 | 
			
		||||
  else
 | 
			
		||||
  {
 | 
			
		||||
    DDS_LOG(DDS_LC_DISCOVERY, " (PARTICIPANT_LEASE_DURATION defaulting to 100s)");
 | 
			
		||||
    GVLOGDISC (" (PARTICIPANT_LEASE_DURATION defaulting to 100s)");
 | 
			
		||||
    lease_duration = 100 * T_SECOND;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -626,13 +628,13 @@ static int handle_SPDP_alive (const struct receiver_state *rst, seqno_t seq, nn_
 | 
			
		|||
        (datap->prismtech_participant_version_info.flags & NN_PRISMTECH_FL_PARTICIPANT_IS_DDSI2))
 | 
			
		||||
      custom_flags |= CF_PARTICIPANT_IS_DDSI2;
 | 
			
		||||
 | 
			
		||||
    DDS_LOG(DDS_LC_DISCOVERY, " (0x%08x-0x%08x-0x%08x-0x%08x-0x%08x %s)",
 | 
			
		||||
            datap->prismtech_participant_version_info.version,
 | 
			
		||||
            datap->prismtech_participant_version_info.flags,
 | 
			
		||||
            datap->prismtech_participant_version_info.unused[0],
 | 
			
		||||
            datap->prismtech_participant_version_info.unused[1],
 | 
			
		||||
            datap->prismtech_participant_version_info.unused[2],
 | 
			
		||||
            datap->prismtech_participant_version_info.internals);
 | 
			
		||||
    GVLOGDISC (" (0x%08x-0x%08x-0x%08x-0x%08x-0x%08x %s)",
 | 
			
		||||
               datap->prismtech_participant_version_info.version,
 | 
			
		||||
               datap->prismtech_participant_version_info.flags,
 | 
			
		||||
               datap->prismtech_participant_version_info.unused[0],
 | 
			
		||||
               datap->prismtech_participant_version_info.unused[1],
 | 
			
		||||
               datap->prismtech_participant_version_info.unused[2],
 | 
			
		||||
               datap->prismtech_participant_version_info.internals);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /* If any of the SEDP announcer are missing AND the guid prefix of
 | 
			
		||||
| 
						 | 
				
			
			@ -646,7 +648,7 @@ static int handle_SPDP_alive (const struct receiver_state *rst, seqno_t seq, nn_
 | 
			
		|||
  if ((builtin_endpoint_set & bes_sedp_announcer_mask) != bes_sedp_announcer_mask &&
 | 
			
		||||
      memcmp (&privileged_pp_guid, &datap->participant_guid, sizeof (nn_guid_t)) != 0)
 | 
			
		||||
  {
 | 
			
		||||
    DDS_LOG(DDS_LC_DISCOVERY, " (depends on "PGUIDFMT")", PGUID (privileged_pp_guid));
 | 
			
		||||
    GVLOGDISC (" (depends on "PGUIDFMT")", PGUID (privileged_pp_guid));
 | 
			
		||||
    /* never expire lease for this proxy: it won't actually expire
 | 
			
		||||
       until the "privileged" one expires anyway */
 | 
			
		||||
    lease_duration = T_NEVER;
 | 
			
		||||
| 
						 | 
				
			
			@ -656,13 +658,13 @@ static int handle_SPDP_alive (const struct receiver_state *rst, seqno_t seq, nn_
 | 
			
		|||
    /* Non-DDSI2 participants are made dependent on DDSI2 (but DDSI2
 | 
			
		||||
       itself need not be discovered yet) */
 | 
			
		||||
    struct proxy_participant *ddsi2;
 | 
			
		||||
    if ((ddsi2 = find_ddsi2_proxy_participant (rst->gv->guid_hash, &datap->participant_guid)) == NULL)
 | 
			
		||||
    if ((ddsi2 = find_ddsi2_proxy_participant (gv->guid_hash, &datap->participant_guid)) == NULL)
 | 
			
		||||
      memset (&privileged_pp_guid.prefix, 0, sizeof (privileged_pp_guid.prefix));
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
      privileged_pp_guid.prefix = ddsi2->e.guid.prefix;
 | 
			
		||||
      lease_duration = T_NEVER;
 | 
			
		||||
      DDS_LOG(DDS_LC_DISCOVERY, " (depends on "PGUIDFMT")", PGUID (privileged_pp_guid));
 | 
			
		||||
      GVLOGDISC (" (depends on "PGUIDFMT")", PGUID (privileged_pp_guid));
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  else
 | 
			
		||||
| 
						 | 
				
			
			@ -678,61 +680,61 @@ static int handle_SPDP_alive (const struct receiver_state *rst, seqno_t seq, nn_
 | 
			
		|||
    as_default = new_addrset ();
 | 
			
		||||
    as_meta = new_addrset ();
 | 
			
		||||
 | 
			
		||||
    if ((datap->present & PP_DEFAULT_MULTICAST_LOCATOR) && (get_locator (rst->gv, &loc, &datap->default_multicast_locators, 0)))
 | 
			
		||||
      allowmulticast_aware_add_to_addrset (rst->gv, rst->gv->config.allowMulticast, as_default, &loc);
 | 
			
		||||
    if ((datap->present & PP_METATRAFFIC_MULTICAST_LOCATOR) && (get_locator (rst->gv, &loc, &datap->metatraffic_multicast_locators, 0)))
 | 
			
		||||
      allowmulticast_aware_add_to_addrset (rst->gv, rst->gv->config.allowMulticast, as_meta, &loc);
 | 
			
		||||
    if ((datap->present & PP_DEFAULT_MULTICAST_LOCATOR) && (get_locator (gv, &loc, &datap->default_multicast_locators, 0)))
 | 
			
		||||
      allowmulticast_aware_add_to_addrset (gv, gv->config.allowMulticast, as_default, &loc);
 | 
			
		||||
    if ((datap->present & PP_METATRAFFIC_MULTICAST_LOCATOR) && (get_locator (gv, &loc, &datap->metatraffic_multicast_locators, 0)))
 | 
			
		||||
      allowmulticast_aware_add_to_addrset (gv, gv->config.allowMulticast, as_meta, &loc);
 | 
			
		||||
 | 
			
		||||
    /* If no multicast locators or multicast TTL > 1, assume IP (multicast) routing can be relied upon to reach
 | 
			
		||||
       the remote participant, else only accept nodes with an advertised unicast address in the same subnet to
 | 
			
		||||
       protect against multicasts being received over an unexpected interface (which sometimes appears to occur) */
 | 
			
		||||
    if (addrset_empty_mc (as_default) && addrset_empty_mc (as_meta))
 | 
			
		||||
      uc_same_subnet = 0;
 | 
			
		||||
    else if (rst->gv->config.multicast_ttl > 1)
 | 
			
		||||
    else if (gv->config.multicast_ttl > 1)
 | 
			
		||||
      uc_same_subnet = 0;
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
      uc_same_subnet = 1;
 | 
			
		||||
      DDS_LOG(DDS_LC_DISCOVERY, " subnet-filter");
 | 
			
		||||
      GVLOGDISC (" subnet-filter");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* If unicast locators not present, then try to obtain from connection */
 | 
			
		||||
    if (!rst->gv->config.tcp_use_peeraddr_for_unicast && (datap->present & PP_DEFAULT_UNICAST_LOCATOR) && (get_locator (rst->gv, &loc, &datap->default_unicast_locators, uc_same_subnet)))
 | 
			
		||||
      add_to_addrset (rst->gv, as_default, &loc);
 | 
			
		||||
    if (!gv->config.tcp_use_peeraddr_for_unicast && (datap->present & PP_DEFAULT_UNICAST_LOCATOR) && (get_locator (gv, &loc, &datap->default_unicast_locators, uc_same_subnet)))
 | 
			
		||||
      add_to_addrset (gv, as_default, &loc);
 | 
			
		||||
    else {
 | 
			
		||||
      DDS_LOG(DDS_LC_DISCOVERY, " (srclocD)");
 | 
			
		||||
      add_to_addrset (rst->gv, as_default, &rst->srcloc);
 | 
			
		||||
      GVLOGDISC (" (srclocD)");
 | 
			
		||||
      add_to_addrset (gv, as_default, &rst->srcloc);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (!rst->gv->config.tcp_use_peeraddr_for_unicast && (datap->present & PP_METATRAFFIC_UNICAST_LOCATOR) && (get_locator (rst->gv, &loc, &datap->metatraffic_unicast_locators, uc_same_subnet)))
 | 
			
		||||
      add_to_addrset (rst->gv, as_meta, &loc);
 | 
			
		||||
    if (!gv->config.tcp_use_peeraddr_for_unicast && (datap->present & PP_METATRAFFIC_UNICAST_LOCATOR) && (get_locator (gv, &loc, &datap->metatraffic_unicast_locators, uc_same_subnet)))
 | 
			
		||||
      add_to_addrset (gv, as_meta, &loc);
 | 
			
		||||
    else {
 | 
			
		||||
      DDS_LOG(DDS_LC_DISCOVERY, " (srclocM)");
 | 
			
		||||
      add_to_addrset (rst->gv, as_meta, &rst->srcloc);
 | 
			
		||||
      GVLOGDISC (" (srclocM)");
 | 
			
		||||
      add_to_addrset (gv, as_meta, &rst->srcloc);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    nn_log_addrset(rst->gv, DDS_LC_DISCOVERY, " (data", as_default);
 | 
			
		||||
    nn_log_addrset(rst->gv, DDS_LC_DISCOVERY, " meta", as_meta);
 | 
			
		||||
    DDS_LOG(DDS_LC_DISCOVERY, ")");
 | 
			
		||||
    nn_log_addrset (gv, DDS_LC_DISCOVERY, " (data", as_default);
 | 
			
		||||
    nn_log_addrset (gv, DDS_LC_DISCOVERY, " meta", as_meta);
 | 
			
		||||
    GVLOGDISC (")");
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (addrset_empty_uc (as_default) || addrset_empty_uc (as_meta))
 | 
			
		||||
  {
 | 
			
		||||
    DDS_LOG(DDS_LC_DISCOVERY, " (no unicast address");
 | 
			
		||||
    GVLOGDISC (" (no unicast address");
 | 
			
		||||
    unref_addrset (as_default);
 | 
			
		||||
    unref_addrset (as_meta);
 | 
			
		||||
    return 1;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  DDS_LOG(DDS_LC_DISCOVERY, " QOS={");
 | 
			
		||||
  nn_log_xqos(DDS_LC_DISCOVERY, &datap->qos);
 | 
			
		||||
  DDS_LOG(DDS_LC_DISCOVERY, "}\n");
 | 
			
		||||
  GVLOGDISC (" QOS={");
 | 
			
		||||
  nn_log_xqos (DDS_LC_DISCOVERY, &gv->logconfig, &datap->qos);
 | 
			
		||||
  GVLOGDISC ("}\n");
 | 
			
		||||
 | 
			
		||||
  maybe_add_pp_as_meta_to_as_disc (rst->gv, as_meta);
 | 
			
		||||
  maybe_add_pp_as_meta_to_as_disc (gv, as_meta);
 | 
			
		||||
 | 
			
		||||
  new_proxy_participant
 | 
			
		||||
  (
 | 
			
		||||
    rst->gv,
 | 
			
		||||
    gv,
 | 
			
		||||
    &datap->participant_guid,
 | 
			
		||||
    builtin_endpoint_set,
 | 
			
		||||
    prismtech_builtin_endpoint_set,
 | 
			
		||||
| 
						 | 
				
			
			@ -755,12 +757,12 @@ static int handle_SPDP_alive (const struct receiver_state *rst, seqno_t seq, nn_
 | 
			
		|||
      (rst->dst_guid_prefix.u[0] != 0 || rst->dst_guid_prefix.u[1] != 0 || rst->dst_guid_prefix.u[2] != 0);
 | 
			
		||||
    if (!have_dst)
 | 
			
		||||
    {
 | 
			
		||||
      DDS_LOG(DDS_LC_DISCOVERY, "broadcasted SPDP packet -> answering");
 | 
			
		||||
      respond_to_spdp (rst->gv, &datap->participant_guid);
 | 
			
		||||
      GVLOGDISC ("broadcasted SPDP packet -> answering");
 | 
			
		||||
      respond_to_spdp (gv, &datap->participant_guid);
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
      DDS_LOG(DDS_LC_DISCOVERY, "directed SPDP packet -> not responding\n");
 | 
			
		||||
      GVLOGDISC ("directed SPDP packet -> not responding\n");
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -768,17 +770,18 @@ static int handle_SPDP_alive (const struct receiver_state *rst, seqno_t seq, nn_
 | 
			
		|||
  {
 | 
			
		||||
    /* If we just discovered DDSI2, make sure any existing
 | 
			
		||||
       participants served by it are made dependent on it */
 | 
			
		||||
    make_participants_dependent_on_ddsi2 (rst->gv, &datap->participant_guid, timestamp);
 | 
			
		||||
    make_participants_dependent_on_ddsi2 (gv, &datap->participant_guid, timestamp);
 | 
			
		||||
  }
 | 
			
		||||
  else if (privileged_pp_guid.prefix.u[0] || privileged_pp_guid.prefix.u[1] || privileged_pp_guid.prefix.u[2])
 | 
			
		||||
  {
 | 
			
		||||
    /* If we just created a participant dependent on DDSI2, make sure
 | 
			
		||||
       DDSI2 still exists.  There is a risk of racing the lease expiry
 | 
			
		||||
       of DDSI2. */
 | 
			
		||||
    if (ephash_lookup_proxy_participant_guid (rst->gv->guid_hash, &privileged_pp_guid) == NULL)
 | 
			
		||||
    if (ephash_lookup_proxy_participant_guid (gv->guid_hash, &privileged_pp_guid) == NULL)
 | 
			
		||||
    {
 | 
			
		||||
      DDS_LOG(DDS_LC_DISCOVERY, "make_participants_dependent_on_ddsi2: ddsi2 "PGUIDFMT" is no more, delete "PGUIDFMT"\n", PGUID (privileged_pp_guid), PGUID (datap->participant_guid));
 | 
			
		||||
      delete_proxy_participant_by_guid (rst->gv, &datap->participant_guid, timestamp, 1);
 | 
			
		||||
      GVLOGDISC ("make_participants_dependent_on_ddsi2: ddsi2 "PGUIDFMT" is no more, delete "PGUIDFMT"\n",
 | 
			
		||||
                 PGUID (privileged_pp_guid), PGUID (datap->participant_guid));
 | 
			
		||||
      delete_proxy_participant_by_guid (gv, &datap->participant_guid, timestamp, 1);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  return 1;
 | 
			
		||||
| 
						 | 
				
			
			@ -786,11 +789,12 @@ static int handle_SPDP_alive (const struct receiver_state *rst, seqno_t seq, nn_
 | 
			
		|||
 | 
			
		||||
static void handle_SPDP (const struct receiver_state *rst, seqno_t seq, nn_wctime_t timestamp, unsigned statusinfo, const void *vdata, uint32_t len)
 | 
			
		||||
{
 | 
			
		||||
  struct q_globals * const gv = rst->gv;
 | 
			
		||||
  const struct CDRHeader *data = vdata; /* built-ins not deserialized (yet) */
 | 
			
		||||
  DDS_TRACE("SPDP ST%x", statusinfo);
 | 
			
		||||
  RSTTRACE("SPDP ST%x", statusinfo);
 | 
			
		||||
  if (data == NULL)
 | 
			
		||||
  {
 | 
			
		||||
    DDS_TRACE(" no payload?\n");
 | 
			
		||||
    RSTTRACE(" no payload?\n");
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
  else
 | 
			
		||||
| 
						 | 
				
			
			@ -804,12 +808,13 @@ static void handle_SPDP (const struct receiver_state *rst, seqno_t seq, nn_wctim
 | 
			
		|||
    src.encoding = data->identifier;
 | 
			
		||||
    src.buf = (unsigned char *) data + 4;
 | 
			
		||||
    src.bufsz = len - 4;
 | 
			
		||||
    src.strict = NN_STRICT_P (rst->gv->config);
 | 
			
		||||
    src.factory = rst->gv->m_factory;
 | 
			
		||||
    src.strict = NN_STRICT_P (gv->config);
 | 
			
		||||
    src.factory = gv->m_factory;
 | 
			
		||||
    src.logconfig = &gv->logconfig;
 | 
			
		||||
    if ((plist_ret = nn_plist_init_frommsg (&decoded_data, NULL, ~(uint64_t)0, ~(uint64_t)0, &src)) < 0)
 | 
			
		||||
    {
 | 
			
		||||
      if (plist_ret != DDS_RETCODE_UNSUPPORTED)
 | 
			
		||||
        DDS_WARNING("SPDP (vendor %u.%u): invalid qos/parameters\n", src.vendorid.id[0], src.vendorid.id[1]);
 | 
			
		||||
        GVWARNING ("SPDP (vendor %u.%u): invalid qos/parameters\n", src.vendorid.id[0], src.vendorid.id[1]);
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -827,7 +832,7 @@ static void handle_SPDP (const struct receiver_state *rst, seqno_t seq, nn_wctim
 | 
			
		|||
    }
 | 
			
		||||
 | 
			
		||||
    nn_plist_fini (&decoded_data);
 | 
			
		||||
    DDS_LOG(interesting ? DDS_LC_DISCOVERY : DDS_LC_TRACE, "\n");
 | 
			
		||||
    GVLOG (interesting ? DDS_LC_DISCOVERY : DDS_LC_TRACE, "\n");
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -880,7 +885,8 @@ static int sedp_write_endpoint
 | 
			
		|||
   const struct entity_common *common, const struct endpoint_common *epcommon,
 | 
			
		||||
   const dds_qos_t *xqos, struct addrset *as)
 | 
			
		||||
{
 | 
			
		||||
  const dds_qos_t *defqos = is_writer_entityid (epguid->entityid) ? &wr->e.gv->default_xqos_wr : &wr->e.gv->default_xqos_rd;
 | 
			
		||||
  struct q_globals * const gv = wr->e.gv;
 | 
			
		||||
  const dds_qos_t *defqos = is_writer_entityid (epguid->entityid) ? &gv->default_xqos_wr : &gv->default_xqos_rd;
 | 
			
		||||
  struct nn_xmsg *mpayload;
 | 
			
		||||
  uint64_t qosdiff;
 | 
			
		||||
  nn_plist_t ps;
 | 
			
		||||
| 
						 | 
				
			
			@ -925,7 +931,7 @@ static int sedp_write_endpoint
 | 
			
		|||
     the default. */
 | 
			
		||||
    if (!is_writer_entityid (epguid->entityid))
 | 
			
		||||
    {
 | 
			
		||||
      const struct reader *rd = ephash_lookup_reader_guid (wr->e.gv->guid_hash, epguid);
 | 
			
		||||
      const struct reader *rd = ephash_lookup_reader_guid (gv->guid_hash, epguid);
 | 
			
		||||
      assert (rd);
 | 
			
		||||
      if (rd->favours_ssm)
 | 
			
		||||
      {
 | 
			
		||||
| 
						 | 
				
			
			@ -936,13 +942,13 @@ static int sedp_write_endpoint
 | 
			
		|||
#endif
 | 
			
		||||
 | 
			
		||||
    qosdiff = nn_xqos_delta (xqos, defqos, ~(uint64_t)0);
 | 
			
		||||
    if (wr->e.gv->config.explicitly_publish_qos_set_to_default)
 | 
			
		||||
    if (gv->config.explicitly_publish_qos_set_to_default)
 | 
			
		||||
      qosdiff |= ~QP_UNRECOGNIZED_INCOMPATIBLE_MASK;
 | 
			
		||||
 | 
			
		||||
    if (as)
 | 
			
		||||
    {
 | 
			
		||||
      struct add_locator_to_ps_arg arg;
 | 
			
		||||
      arg.gv = wr->e.gv;
 | 
			
		||||
      arg.gv = gv;
 | 
			
		||||
      arg.ps = &ps;
 | 
			
		||||
      addrset_forall (as, add_locator_to_ps, &arg);
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -952,13 +958,13 @@ static int sedp_write_endpoint
 | 
			
		|||
     the QoS and other settings. So the header fields aren't really
 | 
			
		||||
     important, except that they need to be set to reasonable things
 | 
			
		||||
     or it'll crash */
 | 
			
		||||
  mpayload = nn_xmsg_new (wr->e.gv->xmsgpool, &wr->e.guid.prefix, 0, NN_XMSG_KIND_DATA);
 | 
			
		||||
  mpayload = nn_xmsg_new (gv->xmsgpool, &wr->e.guid.prefix, 0, NN_XMSG_KIND_DATA);
 | 
			
		||||
  nn_plist_addtomsg (mpayload, &ps, ~(uint64_t)0, ~(uint64_t)0);
 | 
			
		||||
  if (xqos) nn_xqos_addtomsg (mpayload, xqos, qosdiff);
 | 
			
		||||
  nn_xmsg_addpar_sentinel (mpayload);
 | 
			
		||||
  nn_plist_fini (&ps);
 | 
			
		||||
 | 
			
		||||
  DDS_LOG(DDS_LC_DISCOVERY, "sedp: write for "PGUIDFMT" via "PGUIDFMT"\n", PGUID (*epguid), PGUID (wr->e.guid));
 | 
			
		||||
  GVLOGDISC ("sedp: write for "PGUIDFMT" via "PGUIDFMT"\n", PGUID (*epguid), PGUID (wr->e.guid));
 | 
			
		||||
  ret = write_mpayload (wr, alive, PID_ENDPOINT_GUID, mpayload);
 | 
			
		||||
  nn_xmsg_free (mpayload);
 | 
			
		||||
  return ret;
 | 
			
		||||
| 
						 | 
				
			
			@ -968,7 +974,7 @@ static struct writer *get_sedp_writer (const struct participant *pp, unsigned en
 | 
			
		|||
{
 | 
			
		||||
  struct writer *sedp_wr = get_builtin_writer (pp, entityid);
 | 
			
		||||
  if (sedp_wr == NULL)
 | 
			
		||||
    DDS_FATAL("sedp_write_writer: no SEDP builtin writer %x for "PGUIDFMT"\n", entityid, PGUID (pp->e.guid));
 | 
			
		||||
    DDS_FATAL ("sedp_write_writer: no SEDP builtin writer %x for "PGUIDFMT"\n", entityid, PGUID (pp->e.guid));
 | 
			
		||||
  return sedp_wr;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1051,14 +1057,14 @@ static struct proxy_participant *implicitly_create_proxypp (struct q_globals *gv
 | 
			
		|||
  {
 | 
			
		||||
    nn_vendorid_t actual_vendorid;
 | 
			
		||||
    /* Some endpoint that we discovered through the DS, but then it must have at least some locators */
 | 
			
		||||
    DDS_TRACE(" from-DS %"PRIx32":%"PRIx32":%"PRIx32":%"PRIx32, PGUID (privguid));
 | 
			
		||||
    GVTRACE (" from-DS %"PRIx32":%"PRIx32":%"PRIx32":%"PRIx32, PGUID (privguid));
 | 
			
		||||
    /* avoid "no address" case, so we never create the proxy participant for nothing (FIXME: rework some of this) */
 | 
			
		||||
    if (!(datap->present & (PP_UNICAST_LOCATOR | PP_MULTICAST_LOCATOR)))
 | 
			
		||||
    {
 | 
			
		||||
      DDS_TRACE(" data locator absent\n");
 | 
			
		||||
      GVTRACE (" data locator absent\n");
 | 
			
		||||
      goto err;
 | 
			
		||||
    }
 | 
			
		||||
    DDS_TRACE(" new-proxypp "PGUIDFMT"\n", PGUID (*ppguid));
 | 
			
		||||
    GVTRACE (" new-proxypp "PGUIDFMT"\n", PGUID (*ppguid));
 | 
			
		||||
    /* We need to handle any source of entities, but we really want to try to keep the GIDs (and
 | 
			
		||||
       certainly the systemId component) unchanged for OSPL.  The new proxy participant will take
 | 
			
		||||
       the GID from the GUID if it is from a "modern" OSPL that advertises it includes all GIDs in
 | 
			
		||||
| 
						 | 
				
			
			@ -1080,18 +1086,18 @@ static struct proxy_participant *implicitly_create_proxypp (struct q_globals *gv
 | 
			
		|||
       with a minimal built-in endpoint set */
 | 
			
		||||
    struct proxy_participant *privpp;
 | 
			
		||||
    if ((privpp = ephash_lookup_proxy_participant_guid (gv->guid_hash, &privguid)) == NULL) {
 | 
			
		||||
      DDS_TRACE(" unknown-src-proxypp?\n");
 | 
			
		||||
      GVTRACE (" unknown-src-proxypp?\n");
 | 
			
		||||
      goto err;
 | 
			
		||||
    } else if (!privpp->is_ddsi2_pp) {
 | 
			
		||||
      DDS_TRACE(" src-proxypp-not-ddsi2?\n");
 | 
			
		||||
      GVTRACE (" src-proxypp-not-ddsi2?\n");
 | 
			
		||||
      goto err;
 | 
			
		||||
    } else if (!privpp->minimal_bes_mode) {
 | 
			
		||||
      DDS_TRACE(" src-ddsi2-not-minimal-bes-mode?\n");
 | 
			
		||||
      GVTRACE (" src-ddsi2-not-minimal-bes-mode?\n");
 | 
			
		||||
      goto err;
 | 
			
		||||
    } else {
 | 
			
		||||
      struct addrset *as_default, *as_meta;
 | 
			
		||||
      nn_plist_t tmp_plist;
 | 
			
		||||
      DDS_TRACE(" from-ddsi2 "PGUIDFMT, PGUID (privguid));
 | 
			
		||||
      GVTRACE (" from-ddsi2 "PGUIDFMT, PGUID (privguid));
 | 
			
		||||
      nn_plist_init_empty (&pp_plist);
 | 
			
		||||
 | 
			
		||||
      ddsrt_mutex_lock (&privpp->e.lock);
 | 
			
		||||
| 
						 | 
				
			
			@ -1116,7 +1122,8 @@ static struct proxy_participant *implicitly_create_proxypp (struct q_globals *gv
 | 
			
		|||
 | 
			
		||||
static void handle_SEDP_alive (const struct receiver_state *rst, nn_plist_t *datap /* note: potentially modifies datap */, const nn_guid_prefix_t *src_guid_prefix, nn_vendorid_t vendorid, nn_wctime_t timestamp)
 | 
			
		||||
{
 | 
			
		||||
#define E(msg, lbl) do { DDS_LOG(DDS_LC_DISCOVERY, msg); goto lbl; } while (0)
 | 
			
		||||
#define E(msg, lbl) do { GVLOGDISC (msg); goto lbl; } while (0)
 | 
			
		||||
  struct q_globals * const gv = rst->gv;
 | 
			
		||||
  struct proxy_participant *pp;
 | 
			
		||||
  struct proxy_writer * pwr = NULL;
 | 
			
		||||
  struct proxy_reader * prd = NULL;
 | 
			
		||||
| 
						 | 
				
			
			@ -1133,14 +1140,14 @@ static void handle_SEDP_alive (const struct receiver_state *rst, nn_plist_t *dat
 | 
			
		|||
 | 
			
		||||
  if (!(datap->present & PP_ENDPOINT_GUID))
 | 
			
		||||
    E (" no guid?\n", err);
 | 
			
		||||
  DDS_LOG(DDS_LC_DISCOVERY, " "PGUIDFMT, PGUID (datap->endpoint_guid));
 | 
			
		||||
  GVLOGDISC (" "PGUIDFMT, PGUID (datap->endpoint_guid));
 | 
			
		||||
 | 
			
		||||
  ppguid.prefix = datap->endpoint_guid.prefix;
 | 
			
		||||
  ppguid.entityid.u = NN_ENTITYID_PARTICIPANT;
 | 
			
		||||
  if (is_deleted_participant_guid (rst->gv->deleted_participants, &ppguid, DPG_REMOTE))
 | 
			
		||||
  if (is_deleted_participant_guid (gv->deleted_participants, &ppguid, DPG_REMOTE))
 | 
			
		||||
    E (" local dead pp?\n", err);
 | 
			
		||||
 | 
			
		||||
  if (ephash_lookup_participant_guid (rst->gv->guid_hash, &ppguid) != NULL)
 | 
			
		||||
  if (ephash_lookup_participant_guid (gv->guid_hash, &ppguid) != NULL)
 | 
			
		||||
    E (" local pp?\n", err);
 | 
			
		||||
 | 
			
		||||
  if (is_builtin_entityid (datap->endpoint_guid.entityid, vendorid))
 | 
			
		||||
| 
						 | 
				
			
			@ -1150,23 +1157,23 @@ static void handle_SEDP_alive (const struct receiver_state *rst, nn_plist_t *dat
 | 
			
		|||
  if (!(datap->qos.present & QP_TYPE_NAME))
 | 
			
		||||
    E (" no typename?\n", err);
 | 
			
		||||
 | 
			
		||||
  if ((pp = ephash_lookup_proxy_participant_guid (rst->gv->guid_hash, &ppguid)) == NULL)
 | 
			
		||||
  if ((pp = ephash_lookup_proxy_participant_guid (gv->guid_hash, &ppguid)) == NULL)
 | 
			
		||||
  {
 | 
			
		||||
    DDS_LOG(DDS_LC_DISCOVERY, " unknown-proxypp");
 | 
			
		||||
    if ((pp = implicitly_create_proxypp (rst->gv, &ppguid, datap, src_guid_prefix, vendorid, timestamp, 0)) == NULL)
 | 
			
		||||
    GVLOGDISC (" unknown-proxypp");
 | 
			
		||||
    if ((pp = implicitly_create_proxypp (gv, &ppguid, datap, src_guid_prefix, vendorid, timestamp, 0)) == NULL)
 | 
			
		||||
      E ("?\n", err);
 | 
			
		||||
    /* Repeat regular SEDP trace for convenience */
 | 
			
		||||
    DDS_LOG(DDS_LC_DISCOVERY, "SEDP ST0 "PGUIDFMT" (cont)", PGUID (datap->endpoint_guid));
 | 
			
		||||
    GVLOGDISC ("SEDP ST0 "PGUIDFMT" (cont)", PGUID (datap->endpoint_guid));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  xqos = &datap->qos;
 | 
			
		||||
  is_writer = is_writer_entityid (datap->endpoint_guid.entityid);
 | 
			
		||||
  if (!is_writer)
 | 
			
		||||
    nn_xqos_mergein_missing (xqos, &rst->gv->default_xqos_rd, ~(uint64_t)0);
 | 
			
		||||
    nn_xqos_mergein_missing (xqos, &gv->default_xqos_rd, ~(uint64_t)0);
 | 
			
		||||
  else if (vendor_is_eclipse_or_prismtech(vendorid))
 | 
			
		||||
    nn_xqos_mergein_missing (xqos, &rst->gv->default_xqos_wr, ~(uint64_t)0);
 | 
			
		||||
    nn_xqos_mergein_missing (xqos, &gv->default_xqos_wr, ~(uint64_t)0);
 | 
			
		||||
  else
 | 
			
		||||
    nn_xqos_mergein_missing (xqos, &rst->gv->default_xqos_wr_nad, ~(uint64_t)0);
 | 
			
		||||
    nn_xqos_mergein_missing (xqos, &gv->default_xqos_wr_nad, ~(uint64_t)0);
 | 
			
		||||
 | 
			
		||||
  /* After copy + merge, should have at least the ones present in the
 | 
			
		||||
     input.  Also verify reliability and durability are present,
 | 
			
		||||
| 
						 | 
				
			
			@ -1176,14 +1183,14 @@ static void handle_SEDP_alive (const struct receiver_state *rst, nn_plist_t *dat
 | 
			
		|||
  assert (xqos->present & QP_DURABILITY);
 | 
			
		||||
  reliable = (xqos->reliability.kind == DDS_RELIABILITY_RELIABLE);
 | 
			
		||||
 | 
			
		||||
  DDS_LOG(DDS_LC_DISCOVERY, " %s %s %s: %s%s.%s/%s",
 | 
			
		||||
          reliable ? "reliable" : "best-effort",
 | 
			
		||||
          durability_to_string (xqos->durability.kind),
 | 
			
		||||
          is_writer ? "writer" : "reader",
 | 
			
		||||
          ((!(xqos->present & QP_PARTITION) || xqos->partition.n == 0 || *xqos->partition.strs[0] == '\0')
 | 
			
		||||
           ? "(default)" : xqos->partition.strs[0]),
 | 
			
		||||
          ((xqos->present & QP_PARTITION) && xqos->partition.n > 1) ? "+" : "",
 | 
			
		||||
          xqos->topic_name, xqos->type_name);
 | 
			
		||||
  GVLOGDISC (" %s %s %s: %s%s.%s/%s",
 | 
			
		||||
             reliable ? "reliable" : "best-effort",
 | 
			
		||||
             durability_to_string (xqos->durability.kind),
 | 
			
		||||
             is_writer ? "writer" : "reader",
 | 
			
		||||
             ((!(xqos->present & QP_PARTITION) || xqos->partition.n == 0 || *xqos->partition.strs[0] == '\0')
 | 
			
		||||
              ? "(default)" : xqos->partition.strs[0]),
 | 
			
		||||
             ((xqos->present & QP_PARTITION) && xqos->partition.n > 1) ? "+" : "",
 | 
			
		||||
             xqos->topic_name, xqos->type_name);
 | 
			
		||||
 | 
			
		||||
  if (! is_writer && (datap->present & PP_EXPECTS_INLINE_QOS) && datap->expects_inline_qos)
 | 
			
		||||
  {
 | 
			
		||||
| 
						 | 
				
			
			@ -1192,52 +1199,52 @@ static void handle_SEDP_alive (const struct receiver_state *rst, nn_plist_t *dat
 | 
			
		|||
 | 
			
		||||
  if (is_writer)
 | 
			
		||||
  {
 | 
			
		||||
    pwr = ephash_lookup_proxy_writer_guid (rst->gv->guid_hash, &datap->endpoint_guid);
 | 
			
		||||
    pwr = ephash_lookup_proxy_writer_guid (gv->guid_hash, &datap->endpoint_guid);
 | 
			
		||||
  }
 | 
			
		||||
  else
 | 
			
		||||
  {
 | 
			
		||||
    prd = ephash_lookup_proxy_reader_guid (rst->gv->guid_hash, &datap->endpoint_guid);
 | 
			
		||||
    prd = ephash_lookup_proxy_reader_guid (gv->guid_hash, &datap->endpoint_guid);
 | 
			
		||||
  }
 | 
			
		||||
  if (pwr || prd)
 | 
			
		||||
  {
 | 
			
		||||
    /* Re-bind the proxy participant to the discovery service - and do this if it is currently
 | 
			
		||||
       bound to another DS instance, because that other DS instance may have already failed and
 | 
			
		||||
       with a new one taking over, without our noticing it. */
 | 
			
		||||
    DDS_LOG(DDS_LC_DISCOVERY, " known%s", vendor_is_cloud (vendorid) ? "-DS" : "");
 | 
			
		||||
    GVLOGDISC (" known%s", vendor_is_cloud (vendorid) ? "-DS" : "");
 | 
			
		||||
    if (vendor_is_cloud (vendorid) && pp->implicitly_created && memcmp(&pp->privileged_pp_guid.prefix, src_guid_prefix, sizeof(pp->privileged_pp_guid.prefix)) != 0)
 | 
			
		||||
    {
 | 
			
		||||
      nn_etime_t never = { T_NEVER };
 | 
			
		||||
      DDS_LOG(DDS_LC_DISCOVERY, " "PGUIDFMT" attach-to-DS "PGUIDFMT, PGUID(pp->e.guid), PGUIDPREFIX(*src_guid_prefix), pp->privileged_pp_guid.entityid.u);
 | 
			
		||||
      GVLOGDISC (" "PGUIDFMT" attach-to-DS "PGUIDFMT, PGUID(pp->e.guid), PGUIDPREFIX(*src_guid_prefix), pp->privileged_pp_guid.entityid.u);
 | 
			
		||||
      ddsrt_mutex_lock (&pp->e.lock);
 | 
			
		||||
      pp->privileged_pp_guid.prefix = *src_guid_prefix;
 | 
			
		||||
      lease_set_expiry(ddsrt_atomic_ldvoidp(&pp->lease), never);
 | 
			
		||||
      ddsrt_mutex_unlock (&pp->e.lock);
 | 
			
		||||
    }
 | 
			
		||||
    DDS_LOG(DDS_LC_DISCOVERY, "\n");
 | 
			
		||||
    GVLOGDISC ("\n");
 | 
			
		||||
  }
 | 
			
		||||
  else
 | 
			
		||||
  {
 | 
			
		||||
    DDS_LOG(DDS_LC_DISCOVERY, " NEW");
 | 
			
		||||
    GVLOGDISC (" NEW");
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  {
 | 
			
		||||
    nn_locator_t loc;
 | 
			
		||||
    as = new_addrset ();
 | 
			
		||||
    if (!rst->gv->config.tcp_use_peeraddr_for_unicast && (datap->present & PP_UNICAST_LOCATOR) && get_locator (rst->gv, &loc, &datap->unicast_locators, 0))
 | 
			
		||||
      add_to_addrset (rst->gv, as, &loc);
 | 
			
		||||
    else if (rst->gv->config.tcp_use_peeraddr_for_unicast)
 | 
			
		||||
    if (!gv->config.tcp_use_peeraddr_for_unicast && (datap->present & PP_UNICAST_LOCATOR) && get_locator (gv, &loc, &datap->unicast_locators, 0))
 | 
			
		||||
      add_to_addrset (gv, as, &loc);
 | 
			
		||||
    else if (gv->config.tcp_use_peeraddr_for_unicast)
 | 
			
		||||
    {
 | 
			
		||||
      DDS_LOG(DDS_LC_DISCOVERY, " (srcloc)");
 | 
			
		||||
      add_to_addrset (rst->gv, as, &rst->srcloc);
 | 
			
		||||
      GVLOGDISC (" (srcloc)");
 | 
			
		||||
      add_to_addrset (gv, as, &rst->srcloc);
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
      copy_addrset_into_addrset_uc (rst->gv, as, pp->as_default);
 | 
			
		||||
      copy_addrset_into_addrset_uc (gv, as, pp->as_default);
 | 
			
		||||
    }
 | 
			
		||||
    if ((datap->present & PP_MULTICAST_LOCATOR) && get_locator (rst->gv, &loc, &datap->multicast_locators, 0))
 | 
			
		||||
      allowmulticast_aware_add_to_addrset (rst->gv, rst->gv->config.allowMulticast, as, &loc);
 | 
			
		||||
    if ((datap->present & PP_MULTICAST_LOCATOR) && get_locator (gv, &loc, &datap->multicast_locators, 0))
 | 
			
		||||
      allowmulticast_aware_add_to_addrset (gv, gv->config.allowMulticast, as, &loc);
 | 
			
		||||
    else
 | 
			
		||||
      copy_addrset_into_addrset_mc (rst->gv, as, pp->as_default);
 | 
			
		||||
      copy_addrset_into_addrset_mc (gv, as, pp->as_default);
 | 
			
		||||
  }
 | 
			
		||||
  if (addrset_empty (as))
 | 
			
		||||
  {
 | 
			
		||||
| 
						 | 
				
			
			@ -1245,22 +1252,22 @@ static void handle_SEDP_alive (const struct receiver_state *rst, nn_plist_t *dat
 | 
			
		|||
    E (" no address", err);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  nn_log_addrset(rst->gv, DDS_LC_DISCOVERY, " (as", as);
 | 
			
		||||
  nn_log_addrset(gv, DDS_LC_DISCOVERY, " (as", as);
 | 
			
		||||
#ifdef DDSI_INCLUDE_SSM
 | 
			
		||||
  ssm = 0;
 | 
			
		||||
  if (is_writer)
 | 
			
		||||
    ssm = addrset_contains_ssm (rst->gv, as);
 | 
			
		||||
    ssm = addrset_contains_ssm (gv, as);
 | 
			
		||||
  else if (datap->present & PP_READER_FAVOURS_SSM)
 | 
			
		||||
    ssm = (datap->reader_favours_ssm.state != 0);
 | 
			
		||||
  DDS_LOG(DDS_LC_DISCOVERY, " ssm=%u", ssm);
 | 
			
		||||
  GVLOGDISC (" ssm=%u", ssm);
 | 
			
		||||
#endif
 | 
			
		||||
  DDS_LOG(DDS_LC_DISCOVERY, ") QOS={");
 | 
			
		||||
  nn_log_xqos(DDS_LC_DISCOVERY, xqos);
 | 
			
		||||
  DDS_LOG(DDS_LC_DISCOVERY, "}\n");
 | 
			
		||||
  GVLOGDISC (") QOS={");
 | 
			
		||||
  nn_log_xqos (DDS_LC_DISCOVERY, &gv->logconfig, xqos);
 | 
			
		||||
  GVLOGDISC ("}\n");
 | 
			
		||||
 | 
			
		||||
  if ((datap->endpoint_guid.entityid.u & NN_ENTITYID_SOURCE_MASK) == NN_ENTITYID_SOURCE_VENDOR && !vendor_is_eclipse_or_prismtech (vendorid))
 | 
			
		||||
  {
 | 
			
		||||
    DDS_LOG(DDS_LC_DISCOVERY, "ignoring vendor-specific endpoint "PGUIDFMT"\n", PGUID (datap->endpoint_guid));
 | 
			
		||||
    GVLOGDISC ("ignoring vendor-specific endpoint "PGUIDFMT"\n", PGUID (datap->endpoint_guid));
 | 
			
		||||
  }
 | 
			
		||||
  else
 | 
			
		||||
  {
 | 
			
		||||
| 
						 | 
				
			
			@ -1276,11 +1283,11 @@ static void handle_SEDP_alive (const struct receiver_state *rst, nn_plist_t *dat
 | 
			
		|||
        assert (!is_builtin_entityid (datap->endpoint_guid.entityid, vendorid));
 | 
			
		||||
#ifdef DDSI_INCLUDE_NETWORK_CHANNELS
 | 
			
		||||
        {
 | 
			
		||||
          struct config_channel_listelem *channel = find_channel (&rst->gv->config, xqos->transport_priority);
 | 
			
		||||
          new_proxy_writer (&ppguid, &datap->endpoint_guid, as, datap, channel->dqueue, channel->evq ? channel->evq : rst->gv->xevents, timestamp);
 | 
			
		||||
          struct config_channel_listelem *channel = find_channel (&gv->config, xqos->transport_priority);
 | 
			
		||||
          new_proxy_writer (&ppguid, &datap->endpoint_guid, as, datap, channel->dqueue, channel->evq ? channel->evq : gv->xevents, timestamp);
 | 
			
		||||
        }
 | 
			
		||||
#else
 | 
			
		||||
        new_proxy_writer (rst->gv, &ppguid, &datap->endpoint_guid, as, datap, rst->gv->user_dqueue, rst->gv->xevents, timestamp);
 | 
			
		||||
        new_proxy_writer (gv, &ppguid, &datap->endpoint_guid, as, datap, gv->user_dqueue, gv->xevents, timestamp);
 | 
			
		||||
#endif
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -1293,9 +1300,9 @@ static void handle_SEDP_alive (const struct receiver_state *rst, nn_plist_t *dat
 | 
			
		|||
      else
 | 
			
		||||
      {
 | 
			
		||||
#ifdef DDSI_INCLUDE_SSM
 | 
			
		||||
        new_proxy_reader (rst->gv, &ppguid, &datap->endpoint_guid, as, datap, timestamp, ssm);
 | 
			
		||||
        new_proxy_reader (gv, &ppguid, &datap->endpoint_guid, as, datap, timestamp, ssm);
 | 
			
		||||
#else
 | 
			
		||||
        new_proxy_reader (rst->gv, &ppguid, &datap->endpoint_guid, as, datap, timestamp);
 | 
			
		||||
        new_proxy_reader (gv, &ppguid, &datap->endpoint_guid, as, datap, timestamp);
 | 
			
		||||
#endif
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -1311,31 +1318,33 @@ err:
 | 
			
		|||
 | 
			
		||||
static void handle_SEDP_dead (const struct receiver_state *rst, nn_plist_t *datap, nn_wctime_t timestamp)
 | 
			
		||||
{
 | 
			
		||||
  struct q_globals * const gv = rst->gv;
 | 
			
		||||
  int res;
 | 
			
		||||
  if (!(datap->present & PP_ENDPOINT_GUID))
 | 
			
		||||
  {
 | 
			
		||||
    DDS_LOG(DDS_LC_DISCOVERY, " no guid?\n");
 | 
			
		||||
    GVLOGDISC (" no guid?\n");
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
  DDS_LOG(DDS_LC_DISCOVERY, " "PGUIDFMT, PGUID (datap->endpoint_guid));
 | 
			
		||||
  GVLOGDISC (" "PGUIDFMT, PGUID (datap->endpoint_guid));
 | 
			
		||||
  if (is_writer_entityid (datap->endpoint_guid.entityid))
 | 
			
		||||
  {
 | 
			
		||||
    res = delete_proxy_writer (rst->gv, &datap->endpoint_guid, timestamp, 0);
 | 
			
		||||
    res = delete_proxy_writer (gv, &datap->endpoint_guid, timestamp, 0);
 | 
			
		||||
  }
 | 
			
		||||
  else
 | 
			
		||||
  {
 | 
			
		||||
    res = delete_proxy_reader (rst->gv, &datap->endpoint_guid, timestamp, 0);
 | 
			
		||||
    res = delete_proxy_reader (gv, &datap->endpoint_guid, timestamp, 0);
 | 
			
		||||
  }
 | 
			
		||||
  DDS_LOG(DDS_LC_DISCOVERY, " %s\n", (res < 0) ? " unknown" : " delete");
 | 
			
		||||
  GVLOGDISC (" %s\n", (res < 0) ? " unknown" : " delete");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void handle_SEDP (const struct receiver_state *rst, nn_wctime_t timestamp, unsigned statusinfo, const void *vdata, uint32_t len)
 | 
			
		||||
{
 | 
			
		||||
  struct q_globals * const gv = rst->gv;
 | 
			
		||||
  const struct CDRHeader *data = vdata; /* built-ins not deserialized (yet) */
 | 
			
		||||
  DDS_LOG(DDS_LC_DISCOVERY, "SEDP ST%x", statusinfo);
 | 
			
		||||
  GVLOGDISC ("SEDP ST%x", statusinfo);
 | 
			
		||||
  if (data == NULL)
 | 
			
		||||
  {
 | 
			
		||||
    DDS_LOG(DDS_LC_DISCOVERY, " no payload?\n");
 | 
			
		||||
    GVLOGDISC (" no payload?\n");
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
  else
 | 
			
		||||
| 
						 | 
				
			
			@ -1348,12 +1357,13 @@ static void handle_SEDP (const struct receiver_state *rst, nn_wctime_t timestamp
 | 
			
		|||
    src.encoding = data->identifier;
 | 
			
		||||
    src.buf = (unsigned char *) data + 4;
 | 
			
		||||
    src.bufsz = len - 4;
 | 
			
		||||
    src.strict = NN_STRICT_P (rst->gv->config);
 | 
			
		||||
    src.factory = rst->gv->m_factory;
 | 
			
		||||
    src.strict = NN_STRICT_P (gv->config);
 | 
			
		||||
    src.factory = gv->m_factory;
 | 
			
		||||
    src.logconfig = &gv->logconfig;
 | 
			
		||||
    if ((plist_ret = nn_plist_init_frommsg (&decoded_data, NULL, ~(uint64_t)0, ~(uint64_t)0, &src)) < 0)
 | 
			
		||||
    {
 | 
			
		||||
      if (plist_ret != DDS_RETCODE_UNSUPPORTED)
 | 
			
		||||
        DDS_WARNING("SEDP (vendor %u.%u): invalid qos/parameters\n", src.vendorid.id[0], src.vendorid.id[1]);
 | 
			
		||||
        GVWARNING ("SEDP (vendor %u.%u): invalid qos/parameters\n", src.vendorid.id[0], src.vendorid.id[1]);
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1403,7 +1413,7 @@ int sedp_write_topic (struct participant *pp, const struct nn_plist *datap)
 | 
			
		|||
  nn_plist_addtomsg (mpayload, datap, ~(uint64_t)0, delta);
 | 
			
		||||
  nn_xmsg_addpar_sentinel (mpayload);
 | 
			
		||||
 | 
			
		||||
  DDS_TRACE("sedp: write topic %s via "PGUIDFMT"\n", datap->qos.topic_name, PGUID (sedp_wr->e.guid));
 | 
			
		||||
  ETRACE (pp, "sedp: write topic %s via "PGUIDFMT"\n", datap->qos.topic_name, PGUID (sedp_wr->e.guid));
 | 
			
		||||
  ret = write_mpayload (sedp_wr, 1, PID_TOPIC_NAME, mpayload);
 | 
			
		||||
  nn_xmsg_free (mpayload);
 | 
			
		||||
  return ret;
 | 
			
		||||
| 
						 | 
				
			
			@ -1449,7 +1459,7 @@ int sedp_write_cm_participant (struct participant *pp, int alive)
 | 
			
		|||
  }
 | 
			
		||||
  nn_xmsg_addpar_sentinel (mpayload);
 | 
			
		||||
 | 
			
		||||
  DDS_TRACE("sedp: write CMParticipant ST%x for "PGUIDFMT" via "PGUIDFMT"\n",
 | 
			
		||||
  ETRACE (pp, "sedp: write CMParticipant ST%x for "PGUIDFMT" via "PGUIDFMT"\n",
 | 
			
		||||
          alive ? 0 : NN_STATUSINFO_DISPOSE | NN_STATUSINFO_UNREGISTER, PGUID (pp->e.guid), PGUID (sedp_wr->e.guid));
 | 
			
		||||
  ret = write_mpayload (sedp_wr, alive, PID_PARTICIPANT_GUID, mpayload);
 | 
			
		||||
  nn_xmsg_free (mpayload);
 | 
			
		||||
| 
						 | 
				
			
			@ -1458,13 +1468,14 @@ int sedp_write_cm_participant (struct participant *pp, int alive)
 | 
			
		|||
 | 
			
		||||
static void handle_SEDP_CM (const struct receiver_state *rst, nn_entityid_t wr_entity_id, nn_wctime_t timestamp, uint32_t statusinfo, const void *vdata, uint32_t len)
 | 
			
		||||
{
 | 
			
		||||
  struct q_globals * const gv = rst->gv;
 | 
			
		||||
  const struct CDRHeader *data = vdata; /* built-ins not deserialized (yet) */
 | 
			
		||||
  DDS_LOG(DDS_LC_DISCOVERY, "SEDP_CM ST%x", statusinfo);
 | 
			
		||||
  GVLOGDISC ("SEDP_CM ST%x", statusinfo);
 | 
			
		||||
  assert (wr_entity_id.u == NN_ENTITYID_SEDP_BUILTIN_CM_PARTICIPANT_WRITER);
 | 
			
		||||
  (void) wr_entity_id;
 | 
			
		||||
  if (data == NULL)
 | 
			
		||||
  {
 | 
			
		||||
    DDS_LOG(DDS_LC_DISCOVERY, " no payload?\n");
 | 
			
		||||
    GVLOGDISC (" no payload?\n");
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
  else
 | 
			
		||||
| 
						 | 
				
			
			@ -1477,12 +1488,13 @@ static void handle_SEDP_CM (const struct receiver_state *rst, nn_entityid_t wr_e
 | 
			
		|||
    src.encoding = data->identifier;
 | 
			
		||||
    src.buf = (unsigned char *) data + 4;
 | 
			
		||||
    src.bufsz = len - 4;
 | 
			
		||||
    src.strict = NN_STRICT_P (rst->gv->config);
 | 
			
		||||
    src.factory = rst->gv->m_factory;
 | 
			
		||||
    src.strict = NN_STRICT_P (gv->config);
 | 
			
		||||
    src.factory = gv->m_factory;
 | 
			
		||||
    src.logconfig = &gv->logconfig;
 | 
			
		||||
    if ((plist_ret = nn_plist_init_frommsg (&decoded_data, NULL, ~(uint64_t)0, ~(uint64_t)0, &src)) < 0)
 | 
			
		||||
    {
 | 
			
		||||
      if (plist_ret != DDS_RETCODE_UNSUPPORTED)
 | 
			
		||||
        DDS_WARNING("SEDP_CM (vendor %u.%u): invalid qos/parameters\n", src.vendorid.id[0], src.vendorid.id[1]);
 | 
			
		||||
        GVWARNING ("SEDP_CM (vendor %u.%u): invalid qos/parameters\n", src.vendorid.id[0], src.vendorid.id[1]);
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1491,11 +1503,11 @@ static void handle_SEDP_CM (const struct receiver_state *rst, nn_entityid_t wr_e
 | 
			
		|||
    {
 | 
			
		||||
      struct proxy_participant *proxypp;
 | 
			
		||||
      if (!(decoded_data.present & PP_PARTICIPANT_GUID))
 | 
			
		||||
        DDS_WARNING("SEDP_CM (vendor %u.%u): missing participant GUID\n", src.vendorid.id[0], src.vendorid.id[1]);
 | 
			
		||||
        GVWARNING ("SEDP_CM (vendor %u.%u): missing participant GUID\n", src.vendorid.id[0], src.vendorid.id[1]);
 | 
			
		||||
      else
 | 
			
		||||
      {
 | 
			
		||||
        if ((proxypp = ephash_lookup_proxy_participant_guid (rst->gv->guid_hash, &decoded_data.participant_guid)) == NULL)
 | 
			
		||||
          proxypp = implicitly_create_proxypp (rst->gv, &decoded_data.participant_guid, &decoded_data, &rst->src_guid_prefix, rst->vendor, timestamp, 0);
 | 
			
		||||
        if ((proxypp = ephash_lookup_proxy_participant_guid (gv->guid_hash, &decoded_data.participant_guid)) == NULL)
 | 
			
		||||
          proxypp = implicitly_create_proxypp (gv, &decoded_data.participant_guid, &decoded_data, &rst->src_guid_prefix, rst->vendor, timestamp, 0);
 | 
			
		||||
        if (proxypp != NULL)
 | 
			
		||||
          update_proxy_participant_plist (proxypp, 0, &decoded_data, UPD_PROXYPP_CM, timestamp);
 | 
			
		||||
      }
 | 
			
		||||
| 
						 | 
				
			
			@ -1503,7 +1515,7 @@ static void handle_SEDP_CM (const struct receiver_state *rst, nn_entityid_t wr_e
 | 
			
		|||
 | 
			
		||||
    nn_plist_fini (&decoded_data);
 | 
			
		||||
  }
 | 
			
		||||
  DDS_LOG(DDS_LC_DISCOVERY, "\n");
 | 
			
		||||
  GVLOGDISC ("\n");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/******************************************************************************
 | 
			
		||||
| 
						 | 
				
			
			@ -1542,6 +1554,7 @@ static int defragment (unsigned char **datap, const struct nn_rdata *fragchain,
 | 
			
		|||
 | 
			
		||||
int builtins_dqueue_handler (const struct nn_rsample_info *sampleinfo, const struct nn_rdata *fragchain, UNUSED_ARG (const nn_guid_t *rdguid), UNUSED_ARG (void *qarg))
 | 
			
		||||
{
 | 
			
		||||
  struct q_globals * const gv = sampleinfo->rst->gv;
 | 
			
		||||
  struct proxy_writer *pwr;
 | 
			
		||||
  struct {
 | 
			
		||||
    struct CDRHeader cdr;
 | 
			
		||||
| 
						 | 
				
			
			@ -1605,13 +1618,14 @@ int builtins_dqueue_handler (const struct nn_rsample_info *sampleinfo, const str
 | 
			
		|||
    src.encoding = (msg->smhdr.flags & SMFLAG_ENDIANNESS) ? PL_CDR_LE : PL_CDR_BE;
 | 
			
		||||
    src.buf = NN_RMSG_PAYLOADOFF (fragchain->rmsg, qos_offset);
 | 
			
		||||
    src.bufsz = NN_RDATA_PAYLOAD_OFF (fragchain) - qos_offset;
 | 
			
		||||
    src.strict = NN_STRICT_P (sampleinfo->rst->gv->config);
 | 
			
		||||
    src.factory = sampleinfo->rst->gv->m_factory;
 | 
			
		||||
    src.strict = NN_STRICT_P (gv->config);
 | 
			
		||||
    src.factory = gv->m_factory;
 | 
			
		||||
    src.logconfig = &gv->logconfig;
 | 
			
		||||
    if ((plist_ret = nn_plist_init_frommsg (&qos, NULL, PP_STATUSINFO | PP_KEYHASH, 0, &src)) < 0)
 | 
			
		||||
    {
 | 
			
		||||
      if (plist_ret != DDS_RETCODE_UNSUPPORTED)
 | 
			
		||||
        DDS_WARNING("data(builtin, vendor %u.%u): "PGUIDFMT" #%"PRId64": invalid inline qos\n",
 | 
			
		||||
                    src.vendorid.id[0], src.vendorid.id[1], PGUID (srcguid), sampleinfo->seq);
 | 
			
		||||
        GVWARNING ("data(builtin, vendor %u.%u): "PGUIDFMT" #%"PRId64": invalid inline qos\n",
 | 
			
		||||
                   src.vendorid.id[0], src.vendorid.id[1], PGUID (srcguid), sampleinfo->seq);
 | 
			
		||||
      goto done_upd_deliv;
 | 
			
		||||
    }
 | 
			
		||||
    /* Complex qos bit also gets set when statusinfo bits other than
 | 
			
		||||
| 
						 | 
				
			
			@ -1634,10 +1648,9 @@ int builtins_dqueue_handler (const struct nn_rsample_info *sampleinfo, const str
 | 
			
		|||
  {
 | 
			
		||||
    if (datasz == 0 || !(data_smhdr_flags & DATA_FLAG_DATAFLAG))
 | 
			
		||||
    {
 | 
			
		||||
      DDS_WARNING("data(builtin, vendor %u.%u): "PGUIDFMT" #%"PRId64": "
 | 
			
		||||
                   "built-in data but no payload\n",
 | 
			
		||||
                   sampleinfo->rst->vendor.id[0], sampleinfo->rst->vendor.id[1],
 | 
			
		||||
                   PGUID (srcguid), sampleinfo->seq);
 | 
			
		||||
      GVWARNING ("data(builtin, vendor %u.%u): "PGUIDFMT" #%"PRId64": built-in data but no payload\n",
 | 
			
		||||
                 sampleinfo->rst->vendor.id[0], sampleinfo->rst->vendor.id[1],
 | 
			
		||||
                 PGUID (srcguid), sampleinfo->seq);
 | 
			
		||||
      goto done_upd_deliv;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
| 
						 | 
				
			
			@ -1648,14 +1661,13 @@ int builtins_dqueue_handler (const struct nn_rsample_info *sampleinfo, const str
 | 
			
		|||
       hasn't been checked fully yet. */
 | 
			
		||||
    if (!(data_smhdr_flags & DATA_FLAG_KEYFLAG))
 | 
			
		||||
    {
 | 
			
		||||
      DDS_WARNING("data(builtin, vendor %u.%u): "PGUIDFMT" #%"PRId64": "
 | 
			
		||||
                   "dispose/unregister of built-in data but payload not just key\n",
 | 
			
		||||
                   sampleinfo->rst->vendor.id[0], sampleinfo->rst->vendor.id[1],
 | 
			
		||||
                   PGUID (srcguid), sampleinfo->seq);
 | 
			
		||||
      GVWARNING ("data(builtin, vendor %u.%u): "PGUIDFMT" #%"PRId64": dispose/unregister of built-in data but payload not just key\n",
 | 
			
		||||
                 sampleinfo->rst->vendor.id[0], sampleinfo->rst->vendor.id[1],
 | 
			
		||||
                 PGUID (srcguid), sampleinfo->seq);
 | 
			
		||||
      goto done_upd_deliv;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  else if ((qos.present & PP_KEYHASH) && !NN_STRICT_P(pwr->e.gv->config))
 | 
			
		||||
  else if ((qos.present & PP_KEYHASH) && !NN_STRICT_P(gv->config))
 | 
			
		||||
  {
 | 
			
		||||
    /* For SPDP/SEDP, fake a parameter list with just a keyhash.  For
 | 
			
		||||
       PMD, just use the keyhash directly.  Too hard to fix everything
 | 
			
		||||
| 
						 | 
				
			
			@ -1690,9 +1702,9 @@ int builtins_dqueue_handler (const struct nn_rsample_info *sampleinfo, const str
 | 
			
		|||
          pid = PID_ENDPOINT_GUID;
 | 
			
		||||
          break;
 | 
			
		||||
        default:
 | 
			
		||||
          DDS_LOG(DDS_LC_DISCOVERY, "data(builtin, vendor %u.%u): "PGUIDFMT" #%"PRId64": mapping keyhash to ENDPOINT_GUID",
 | 
			
		||||
                  sampleinfo->rst->vendor.id[0], sampleinfo->rst->vendor.id[1],
 | 
			
		||||
                  PGUID (srcguid), sampleinfo->seq);
 | 
			
		||||
          GVLOGDISC ("data(builtin, vendor %u.%u): "PGUIDFMT" #%"PRId64": mapping keyhash to ENDPOINT_GUID",
 | 
			
		||||
                     sampleinfo->rst->vendor.id[0], sampleinfo->rst->vendor.id[1],
 | 
			
		||||
                     PGUID (srcguid), sampleinfo->seq);
 | 
			
		||||
          pid = PID_ENDPOINT_GUID;
 | 
			
		||||
          break;
 | 
			
		||||
      }
 | 
			
		||||
| 
						 | 
				
			
			@ -1707,10 +1719,9 @@ int builtins_dqueue_handler (const struct nn_rsample_info *sampleinfo, const str
 | 
			
		|||
  }
 | 
			
		||||
  else
 | 
			
		||||
  {
 | 
			
		||||
    DDS_WARNING("data(builtin, vendor %u.%u): "PGUIDFMT" #%"PRId64": "
 | 
			
		||||
                 "dispose/unregister with no content\n",
 | 
			
		||||
                 sampleinfo->rst->vendor.id[0], sampleinfo->rst->vendor.id[1],
 | 
			
		||||
                 PGUID (srcguid), sampleinfo->seq);
 | 
			
		||||
    GVWARNING ("data(builtin, vendor %u.%u): "PGUIDFMT" #%"PRId64": dispose/unregister with no content\n",
 | 
			
		||||
               sampleinfo->rst->vendor.id[0], sampleinfo->rst->vendor.id[1],
 | 
			
		||||
               PGUID (srcguid), sampleinfo->seq);
 | 
			
		||||
    goto done_upd_deliv;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1734,9 +1745,9 @@ int builtins_dqueue_handler (const struct nn_rsample_info *sampleinfo, const str
 | 
			
		|||
      handle_SEDP_CM (sampleinfo->rst, srcguid.entityid, timestamp, statusinfo, datap, datasz);
 | 
			
		||||
      break;
 | 
			
		||||
    default:
 | 
			
		||||
      DDS_LOG (DDS_LC_DISCOVERY, "data(builtin, vendor %u.%u): "PGUIDFMT" #%"PRId64": not handled\n",
 | 
			
		||||
               sampleinfo->rst->vendor.id[0], sampleinfo->rst->vendor.id[1],
 | 
			
		||||
               PGUID (srcguid), sampleinfo->seq);
 | 
			
		||||
      GVLOGDISC ("data(builtin, vendor %u.%u): "PGUIDFMT" #%"PRId64": not handled\n",
 | 
			
		||||
                 sampleinfo->rst->vendor.id[0], sampleinfo->rst->vendor.id[1],
 | 
			
		||||
                 PGUID (srcguid), sampleinfo->seq);
 | 
			
		||||
      break;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -364,7 +364,7 @@ struct debug_monitor *new_debug_monitor (struct q_globals *gv, int port)
 | 
			
		|||
  dm->servsock = ddsi_factory_create_listener (dm->tran_factory, port, NULL);
 | 
			
		||||
  if (dm->servsock == NULL)
 | 
			
		||||
  {
 | 
			
		||||
    DDS_WARNING("debmon: can't create socket\n");
 | 
			
		||||
    GVWARNING ("debmon: can't create socket\n");
 | 
			
		||||
    goto err_servsock;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -372,7 +372,7 @@ struct debug_monitor *new_debug_monitor (struct q_globals *gv, int port)
 | 
			
		|||
    nn_locator_t loc;
 | 
			
		||||
    char buf[DDSI_LOCSTRLEN];
 | 
			
		||||
    (void) ddsi_listener_locator(dm->servsock, &loc);
 | 
			
		||||
    DDS_LOG(DDS_LC_CONFIG, "debmon at %s\n", ddsi_locator_to_string (gv, buf, sizeof(buf), &loc));
 | 
			
		||||
    GVLOG (DDS_LC_CONFIG, "debmon at %s\n", ddsi_locator_to_string (gv, buf, sizeof(buf), &loc));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  ddsrt_mutex_init (&dm->lock);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							| 
						 | 
				
			
			@ -100,7 +100,7 @@ static uint32_t gcreq_queue_thread (struct gcreq_queue *q)
 | 
			
		|||
  ddsrt_mutex_lock (&q->lock);
 | 
			
		||||
  while (!(q->terminate && q->count == 0))
 | 
			
		||||
  {
 | 
			
		||||
    LOG_THREAD_CPUTIME (next_thread_cputime);
 | 
			
		||||
    LOG_THREAD_CPUTIME (&q->gv->logconfig, next_thread_cputime);
 | 
			
		||||
 | 
			
		||||
    /* While deaf, we need to make sure the receive thread wakes up
 | 
			
		||||
       every now and then to try recreating sockets & rejoining multicast
 | 
			
		||||
| 
						 | 
				
			
			@ -165,7 +165,7 @@ static uint32_t gcreq_queue_thread (struct gcreq_queue *q)
 | 
			
		|||
           reasonable. */
 | 
			
		||||
        if (trace_shortsleep)
 | 
			
		||||
        {
 | 
			
		||||
          DDS_TRACE("gc %p: not yet, shortsleep\n", (void*)gcreq);
 | 
			
		||||
          DDS_CTRACE (&q->gv->logconfig, "gc %p: not yet, shortsleep\n", (void *) gcreq);
 | 
			
		||||
          trace_shortsleep = 0;
 | 
			
		||||
        }
 | 
			
		||||
        dds_sleepfor (shortsleep);
 | 
			
		||||
| 
						 | 
				
			
			@ -176,7 +176,7 @@ static uint32_t gcreq_queue_thread (struct gcreq_queue *q)
 | 
			
		|||
           it; the callback is responsible for requeueing (if complex
 | 
			
		||||
           multi-phase delete) or freeing the delete request.  Reset
 | 
			
		||||
           the current gcreq as this one obviously is no more.  */
 | 
			
		||||
        DDS_TRACE("gc %p: deleting\n", (void*)gcreq);
 | 
			
		||||
        DDS_CTRACE (&q->gv->logconfig, "gc %p: deleting\n", (void *) gcreq);
 | 
			
		||||
        thread_state_awake_fixed_domain (ts1);
 | 
			
		||||
        gcreq->cb (gcreq);
 | 
			
		||||
        thread_state_asleep (ts1);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -49,6 +49,7 @@
 | 
			
		|||
#include "dds/ddsi/q_feature_check.h"
 | 
			
		||||
#include "dds/ddsi/q_debmon.h"
 | 
			
		||||
#include "dds/ddsi/q_init.h"
 | 
			
		||||
#include "dds/ddsi/ddsi_threadmon.h"
 | 
			
		||||
 | 
			
		||||
#include "dds/ddsi/ddsi_tran.h"
 | 
			
		||||
#include "dds/ddsi/ddsi_udp.h"
 | 
			
		||||
| 
						 | 
				
			
			@ -86,9 +87,9 @@ static int make_uc_sockets (struct q_globals *gv, uint32_t * pdisc, uint32_t * p
 | 
			
		|||
  if (ppid >= 0)
 | 
			
		||||
  {
 | 
			
		||||
    /* FIXME: verify port numbers are in range instead of truncating them like this */
 | 
			
		||||
    int base = gv->config.port_base + (gv->config.port_dg * gv->config.domainId.value) + (ppid * gv->config.port_pg);
 | 
			
		||||
    *pdisc = (uint32_t) (base + gv->config.port_d1);
 | 
			
		||||
    *pdata = (uint32_t) (base + gv->config.port_d3);
 | 
			
		||||
    uint32_t base = gv->config.port_base + (gv->config.port_dg * gv->config.domainId.value) + ((uint32_t) ppid * gv->config.port_pg);
 | 
			
		||||
    *pdisc = base + gv->config.port_d1;
 | 
			
		||||
    *pdata = base + gv->config.port_d3;
 | 
			
		||||
  }
 | 
			
		||||
  else if (ppid == PARTICIPANT_INDEX_NONE)
 | 
			
		||||
  {
 | 
			
		||||
| 
						 | 
				
			
			@ -97,7 +98,7 @@ static int make_uc_sockets (struct q_globals *gv, uint32_t * pdisc, uint32_t * p
 | 
			
		|||
  }
 | 
			
		||||
  else
 | 
			
		||||
  {
 | 
			
		||||
    DDS_FATAL("make_uc_sockets: invalid participant index %d\n", ppid);
 | 
			
		||||
    DDS_FATAL ("make_uc_sockets: invalid participant index %d\n", ppid);
 | 
			
		||||
    return -1;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -150,7 +151,7 @@ static int set_recvips (struct q_globals *gv)
 | 
			
		|||
#if DDSRT_HAVE_IPV6
 | 
			
		||||
      if (gv->ipv6_link_local)
 | 
			
		||||
      {
 | 
			
		||||
        DDS_WARNING("DDSI2EService/General/MulticastRecvNetworkInterfaceAddresses: using 'preferred' instead of 'all' because of IPv6 link-local address\n");
 | 
			
		||||
        GVWARNING ("DDSI2EService/General/MulticastRecvNetworkInterfaceAddresses: using 'preferred' instead of 'all' because of IPv6 link-local address\n");
 | 
			
		||||
        gv->recvips_mode = RECVIPS_MODE_PREFERRED;
 | 
			
		||||
      }
 | 
			
		||||
      else
 | 
			
		||||
| 
						 | 
				
			
			@ -164,7 +165,7 @@ static int set_recvips (struct q_globals *gv)
 | 
			
		|||
#if DDSRT_HAVE_IPV6
 | 
			
		||||
      if (gv->ipv6_link_local)
 | 
			
		||||
      {
 | 
			
		||||
        DDS_ERROR("DDSI2EService/General/MulticastRecvNetworkInterfaceAddresses: 'any' is unsupported in combination with an IPv6 link-local address\n");
 | 
			
		||||
        GVERROR ("DDSI2EService/General/MulticastRecvNetworkInterfaceAddresses: 'any' is unsupported in combination with an IPv6 link-local address\n");
 | 
			
		||||
        return -1;
 | 
			
		||||
      }
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			@ -190,7 +191,7 @@ static int set_recvips (struct q_globals *gv)
 | 
			
		|||
        nn_locator_t loc;
 | 
			
		||||
        if (ddsi_locator_from_string(gv, &loc, gv->config.networkRecvAddressStrings[i], gv->m_factory) != AFSR_OK)
 | 
			
		||||
        {
 | 
			
		||||
          DDS_ERROR("%s: not a valid address in DDSI2EService/General/MulticastRecvNetworkInterfaceAddresses\n", gv->config.networkRecvAddressStrings[i]);
 | 
			
		||||
          GVERROR ("%s: not a valid address in DDSI2EService/General/MulticastRecvNetworkInterfaceAddresses\n", gv->config.networkRecvAddressStrings[i]);
 | 
			
		||||
          return -1;
 | 
			
		||||
        }
 | 
			
		||||
        if (compare_locators(&loc, &gv->interfaces[gv->selected_interface].loc) == 0)
 | 
			
		||||
| 
						 | 
				
			
			@ -201,7 +202,7 @@ static int set_recvips (struct q_globals *gv)
 | 
			
		|||
      gv->recvips_mode = have_selected ? RECVIPS_MODE_PREFERRED : RECVIPS_MODE_NONE;
 | 
			
		||||
      if (have_others)
 | 
			
		||||
      {
 | 
			
		||||
        DDS_WARNING("DDSI2EService/General/MulticastRecvNetworkInterfaceAddresses: using 'preferred' because of IPv6 local address\n");
 | 
			
		||||
        GVWARNING ("DDSI2EService/General/MulticastRecvNetworkInterfaceAddresses: using 'preferred' because of IPv6 local address\n");
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			@ -215,7 +216,7 @@ static int set_recvips (struct q_globals *gv)
 | 
			
		|||
        nn_locator_t loc;
 | 
			
		||||
        if (ddsi_locator_from_string(gv, &loc, gv->config.networkRecvAddressStrings[i], gv->m_factory) != AFSR_OK)
 | 
			
		||||
        {
 | 
			
		||||
          DDS_ERROR("%s: not a valid address in DDSI2EService/General/MulticastRecvNetworkInterfaceAddresses\n", gv->config.networkRecvAddressStrings[i]);
 | 
			
		||||
          GVERROR ("%s: not a valid address in DDSI2EService/General/MulticastRecvNetworkInterfaceAddresses\n", gv->config.networkRecvAddressStrings[i]);
 | 
			
		||||
          return -1;
 | 
			
		||||
        }
 | 
			
		||||
        for (j = 0; j < gv->n_interfaces; j++)
 | 
			
		||||
| 
						 | 
				
			
			@ -225,7 +226,7 @@ static int set_recvips (struct q_globals *gv)
 | 
			
		|||
        }
 | 
			
		||||
        if (j == gv->n_interfaces)
 | 
			
		||||
        {
 | 
			
		||||
          DDS_ERROR("No interface bound to requested address '%s'\n", gv->config.networkRecvAddressStrings[i]);
 | 
			
		||||
          GVERROR ("No interface bound to requested address '%s'\n", gv->config.networkRecvAddressStrings[i]);
 | 
			
		||||
          return -1;
 | 
			
		||||
        }
 | 
			
		||||
        *recvnode = ddsrt_malloc (sizeof (struct config_in_addr_node));
 | 
			
		||||
| 
						 | 
				
			
			@ -256,13 +257,13 @@ static int string_to_default_locator (const struct q_globals *gv, nn_locator_t *
 | 
			
		|||
    case AFSR_OK:
 | 
			
		||||
      break;
 | 
			
		||||
    case AFSR_INVALID:
 | 
			
		||||
      DDS_ERROR("%s: not a valid address (%s)\n", string, tag);
 | 
			
		||||
      GVERROR ("%s: not a valid address (%s)\n", string, tag);
 | 
			
		||||
      return -1;
 | 
			
		||||
    case AFSR_UNKNOWN:
 | 
			
		||||
      DDS_ERROR("%s: address name resolution failure (%s)\n", string, tag);
 | 
			
		||||
      GVERROR ("%s: address name resolution failure (%s)\n", string, tag);
 | 
			
		||||
      return -1;
 | 
			
		||||
    case AFSR_MISMATCH:
 | 
			
		||||
      DDS_ERROR("%s: invalid address kind (%s)\n", string, tag);
 | 
			
		||||
      GVERROR ("%s: invalid address kind (%s)\n", string, tag);
 | 
			
		||||
      return -1;
 | 
			
		||||
  }
 | 
			
		||||
  if (port != 0 && !is_unspec_locator(loc))
 | 
			
		||||
| 
						 | 
				
			
			@ -276,7 +277,7 @@ static int string_to_default_locator (const struct q_globals *gv, nn_locator_t *
 | 
			
		|||
    const int ismc = is_unspec_locator (loc) || ddsi_is_mcaddr (gv, loc);
 | 
			
		||||
    if (mc != ismc)
 | 
			
		||||
    {
 | 
			
		||||
      DDS_ERROR("%s: %s %s be the unspecified address or a multicast address\n", string, tag, rel);
 | 
			
		||||
      GVERROR ("%s: %s %s be the unspecified address or a multicast address\n", string, tag, rel);
 | 
			
		||||
      return -1;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
| 
						 | 
				
			
			@ -308,7 +309,7 @@ static int set_spdp_address (struct q_globals *gv)
 | 
			
		|||
#ifdef DDSI_INCLUDE_SSM
 | 
			
		||||
  if (gv->loc_spdp_mc.kind != NN_LOCATOR_KIND_INVALID && ddsi_is_ssm_mcaddr (gv, &gv->loc_spdp_mc))
 | 
			
		||||
  {
 | 
			
		||||
    DDS_ERROR("%s: SPDP address may not be an SSM address\n", gv->config.spdpMulticastAddressString);
 | 
			
		||||
    GVERROR ("%s: SPDP address may not be an SSM address\n", gv->config.spdpMulticastAddressString);
 | 
			
		||||
    return -1;
 | 
			
		||||
  }
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			@ -339,7 +340,7 @@ static int set_ext_address_and_mask (struct q_globals *gv)
 | 
			
		|||
  else if ((rc = string_to_default_locator (gv, &loc, gv->config.externalAddressString, 0, 0, "external address")) < 0)
 | 
			
		||||
    return rc;
 | 
			
		||||
  else if (rc == 0) {
 | 
			
		||||
    DDS_WARNING("Ignoring ExternalNetworkAddress %s\n", gv->config.externalAddressString);
 | 
			
		||||
    GVWARNING ("Ignoring ExternalNetworkAddress %s\n", gv->config.externalAddressString);
 | 
			
		||||
    gv->extloc = gv->ownloc;
 | 
			
		||||
  } else {
 | 
			
		||||
    gv->extloc = loc;
 | 
			
		||||
| 
						 | 
				
			
			@ -353,7 +354,7 @@ static int set_ext_address_and_mask (struct q_globals *gv)
 | 
			
		|||
  }
 | 
			
		||||
  else if (gv->config.transport_selector != TRANS_UDP)
 | 
			
		||||
  {
 | 
			
		||||
    DDS_ERROR("external network masks only supported in IPv4 mode\n");
 | 
			
		||||
    GVERROR ("external network masks only supported in IPv4 mode\n");
 | 
			
		||||
    return -1;
 | 
			
		||||
  }
 | 
			
		||||
  else
 | 
			
		||||
| 
						 | 
				
			
			@ -403,11 +404,11 @@ static int check_thread_properties (const struct q_globals *gv)
 | 
			
		|||
      }
 | 
			
		||||
      if (chanprefix[i] == NULL)
 | 
			
		||||
      {
 | 
			
		||||
        DDS_ERROR("config: DDSI2Service/Threads/Thread[@name=\"%s\"]: unknown thread\n", e->name);
 | 
			
		||||
        DDS_ILOG (DDS_LC_ERROR, gv->config.domainId.value, "config: DDSI2Service/Threads/Thread[@name=\"%s\"]: unknown thread\n", e->name);
 | 
			
		||||
        ok = 0;
 | 
			
		||||
      }
 | 
			
		||||
#else
 | 
			
		||||
      DDS_ERROR("config: DDSI2Service/Threads/Thread[@name=\"%s\"]: unknown thread\n", e->name);
 | 
			
		||||
      DDS_ILOG (DDS_LC_ERROR, gv->config.domainId.value, "config: DDSI2Service/Threads/Thread[@name=\"%s\"]: unknown thread\n", e->name);
 | 
			
		||||
      ok = 0;
 | 
			
		||||
#endif /* DDSI_INCLUDE_NETWORK_CHANNELS */
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -438,7 +439,7 @@ int rtps_config_open (struct q_globals *gv)
 | 
			
		|||
  }
 | 
			
		||||
  else if ((gv->config.tracingOutputFile = fopen (gv->config.tracingOutputFileName, gv->config.tracingAppendToFile ? "a" : "w")) == NULL)
 | 
			
		||||
  {
 | 
			
		||||
    DDS_ERROR("%s: cannot open for writing\n", gv->config.tracingOutputFileName);
 | 
			
		||||
    DDS_ILOG (DDS_LC_ERROR, gv->config.domainId.value, "%s: cannot open for writing\n", gv->config.tracingOutputFileName);
 | 
			
		||||
    status = 0;
 | 
			
		||||
  }
 | 
			
		||||
  else
 | 
			
		||||
| 
						 | 
				
			
			@ -446,9 +447,7 @@ int rtps_config_open (struct q_globals *gv)
 | 
			
		|||
    status = 1;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  dds_set_log_mask(gv->config.enabled_logcats);
 | 
			
		||||
  dds_set_trace_file(gv->config.tracingOutputFile);
 | 
			
		||||
 | 
			
		||||
  dds_log_cfg_init (&gv->logconfig, gv->config.domainId.value, gv->config.enabled_logcats, stderr, gv->config.tracingOutputFile);
 | 
			
		||||
  return status;
 | 
			
		||||
  DDSRT_WARNING_MSVC_ON(4996);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -467,7 +466,7 @@ int rtps_config_prep (struct q_globals *gv, struct cfgst *cfgst)
 | 
			
		|||
      gv->config.whc_init_highwater_mark.value < gv->config.whc_lowwater_mark ||
 | 
			
		||||
      gv->config.whc_init_highwater_mark.value > gv->config.whc_highwater_mark)
 | 
			
		||||
  {
 | 
			
		||||
    DDS_ERROR("Invalid watermark settings\n");
 | 
			
		||||
    DDS_ILOG (DDS_LC_ERROR, gv->config.domainId.value, "Invalid watermark settings\n");
 | 
			
		||||
    goto err_config_late_error;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -479,7 +478,7 @@ int rtps_config_prep (struct q_globals *gv, struct cfgst *cfgst)
 | 
			
		|||
       inherited by readers/writers), but in many sockets mode each
 | 
			
		||||
       participant has its own socket, and therefore unique address
 | 
			
		||||
       set */
 | 
			
		||||
    DDS_ERROR ("Minimal built-in endpoint set mode and ManySocketsMode are incompatible\n");
 | 
			
		||||
    DDS_ILOG (DDS_LC_ERROR, gv->config.domainId.value, "Minimal built-in endpoint set mode and ManySocketsMode are incompatible\n");
 | 
			
		||||
    goto err_config_late_error;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -500,7 +499,7 @@ int rtps_config_prep (struct q_globals *gv, struct cfgst *cfgst)
 | 
			
		|||
      double max = (double) gv->config.auxiliary_bandwidth_limit * ((double) gv->config.nack_delay / 1e9);
 | 
			
		||||
      if (max < 0)
 | 
			
		||||
      {
 | 
			
		||||
        DDS_ERROR ("AuxiliaryBandwidthLimit * NackDelay = %g bytes is insane\n", max);
 | 
			
		||||
        DDS_ILOG (DDS_LC_ERROR, gv->config.domainId.value, "AuxiliaryBandwidthLimit * NackDelay = %g bytes is insane\n", max);
 | 
			
		||||
        goto err_config_late_error;
 | 
			
		||||
      }
 | 
			
		||||
      gv->config.max_queued_rexmit_bytes = max > 2147483647.0 ? 2147483647u : (unsigned) max;
 | 
			
		||||
| 
						 | 
				
			
			@ -513,7 +512,6 @@ int rtps_config_prep (struct q_globals *gv, struct cfgst *cfgst)
 | 
			
		|||
  /* Verify thread properties refer to defined threads */
 | 
			
		||||
  if (!check_thread_properties (gv))
 | 
			
		||||
  {
 | 
			
		||||
    DDS_TRACE ("Could not initialise configuration\n");
 | 
			
		||||
    goto err_config_late_error;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -537,7 +535,7 @@ int rtps_config_prep (struct q_globals *gv, struct cfgst *cfgst)
 | 
			
		|||
 | 
			
		||||
      if (gv->config.transport_selector != TRANS_UDP && chptr->diffserv_field != 0)
 | 
			
		||||
      {
 | 
			
		||||
        DDS_ERROR ("channel %s specifies IPv4 DiffServ settings which is incompatible with IPv6 use\n", chptr->name);
 | 
			
		||||
        DDS_ILOG (DDS_LC_ERROR, gv->config.domainId.value, "channel %s specifies IPv4 DiffServ settings which is incompatible with IPv6 use\n", chptr->name);
 | 
			
		||||
        error = 1;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -556,11 +554,9 @@ int rtps_config_prep (struct q_globals *gv, struct cfgst *cfgst)
 | 
			
		|||
  }
 | 
			
		||||
#endif /* DDSI_INCLUDE_NETWORK_CHANNELS */
 | 
			
		||||
 | 
			
		||||
  /* Open tracing file after all possible gv->config errors have been
 | 
			
		||||
   printed */
 | 
			
		||||
  /* Open tracing file after all possible gv->config errors have been printed */
 | 
			
		||||
  if (! rtps_config_open (gv))
 | 
			
		||||
  {
 | 
			
		||||
    DDS_TRACE ("Could not initialise configuration\n");
 | 
			
		||||
    goto err_config_late_error;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -586,7 +582,7 @@ int rtps_config_prep (struct q_globals *gv, struct cfgst *cfgst)
 | 
			
		|||
 | 
			
		||||
  /* Now the per-thread-log-buffers are set up, so print the configuration.  After this there
 | 
			
		||||
     is no value to the source information for the various configuration elements, so free those. */
 | 
			
		||||
  config_print_cfgst (cfgst);
 | 
			
		||||
  config_print_cfgst (cfgst, &gv->logconfig);
 | 
			
		||||
  config_free_source_info (cfgst);
 | 
			
		||||
  return 0;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -637,7 +633,7 @@ int joinleave_spdp_defmcip (struct q_globals *gv, int dojoin)
 | 
			
		|||
  unref_addrset (as);
 | 
			
		||||
  if (arg.errcount)
 | 
			
		||||
  {
 | 
			
		||||
    DDS_ERROR("rtps_init: failed to join multicast groups for domain %"PRId32" participant %d\n", gv->config.domainId.value, gv->config.participantIndex);
 | 
			
		||||
    GVERROR ("rtps_init: failed to join multicast groups for domain %"PRIu32" participant %d\n", gv->config.domainId.value, gv->config.participantIndex);
 | 
			
		||||
    return -1;
 | 
			
		||||
  }
 | 
			
		||||
  return 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -669,8 +665,8 @@ int create_multicast_sockets (struct q_globals *gv)
 | 
			
		|||
 | 
			
		||||
  gv->disc_conn_mc = disc;
 | 
			
		||||
  gv->data_conn_mc = data;
 | 
			
		||||
  DDS_TRACE("Multicast Ports: discovery %"PRIu32" data %"PRIu32" \n",
 | 
			
		||||
          ddsi_conn_port (gv->disc_conn_mc), ddsi_conn_port (gv->data_conn_mc));
 | 
			
		||||
  GVTRACE ("Multicast Ports: discovery %"PRIu32" data %"PRIu32" \n",
 | 
			
		||||
           ddsi_conn_port (gv->disc_conn_mc), ddsi_conn_port (gv->data_conn_mc));
 | 
			
		||||
  return 1;
 | 
			
		||||
 | 
			
		||||
err_data:
 | 
			
		||||
| 
						 | 
				
			
			@ -719,7 +715,7 @@ static void wait_for_receive_threads (struct q_globals *gv)
 | 
			
		|||
    /* retrying is to deal a packet geting lost because the socket buffer is full or because the
 | 
			
		||||
       macOS firewall (and perhaps others) likes to ask if the process is allowed to receive data,
 | 
			
		||||
       dropping the packets until the user approves. */
 | 
			
		||||
    DDS_WARNING("wait_for_receive_threads: failed to schedule periodic triggering of the receive threads to deal with packet loss\n");
 | 
			
		||||
    GVWARNING ("wait_for_receive_threads: failed to schedule periodic triggering of the receive threads to deal with packet loss\n");
 | 
			
		||||
  }
 | 
			
		||||
  for (uint32_t i = 0; i < gv->n_recv_threads; i++)
 | 
			
		||||
  {
 | 
			
		||||
| 
						 | 
				
			
			@ -818,22 +814,22 @@ static int setup_and_start_recv_threads (struct q_globals *gv)
 | 
			
		|||
    /* We create the rbufpool for the receive thread, and so we'll
 | 
			
		||||
       become the initial owner thread. The receive thread will change
 | 
			
		||||
       it before it does anything with it. */
 | 
			
		||||
    if ((gv->recv_threads[i].arg.rbpool = nn_rbufpool_new (gv->config.rbuf_size, gv->config.rmsg_chunk_size)) == NULL)
 | 
			
		||||
    if ((gv->recv_threads[i].arg.rbpool = nn_rbufpool_new (&gv->logconfig, gv->config.rbuf_size, gv->config.rmsg_chunk_size)) == NULL)
 | 
			
		||||
    {
 | 
			
		||||
      DDS_ERROR("rtps_init: can't allocate receive buffer pool for thread %s\n", gv->recv_threads[i].name);
 | 
			
		||||
      GVERROR ("rtps_init: can't allocate receive buffer pool for thread %s\n", gv->recv_threads[i].name);
 | 
			
		||||
      goto fail;
 | 
			
		||||
    }
 | 
			
		||||
    if (gv->recv_threads[i].arg.mode == RTM_MANY)
 | 
			
		||||
    {
 | 
			
		||||
      if ((gv->recv_threads[i].arg.u.many.ws = os_sockWaitsetNew ()) == NULL)
 | 
			
		||||
      {
 | 
			
		||||
        DDS_ERROR("rtps_init: can't allocate sock waitset for thread %s\n", gv->recv_threads[i].name);
 | 
			
		||||
        GVERROR ("rtps_init: can't allocate sock waitset for thread %s\n", gv->recv_threads[i].name);
 | 
			
		||||
        goto fail;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    if (create_thread (&gv->recv_threads[i].ts, gv, gv->recv_threads[i].name, recv_thread, &gv->recv_threads[i].arg) != DDS_RETCODE_OK)
 | 
			
		||||
    {
 | 
			
		||||
      DDS_ERROR("rtps_init: failed to start thread %s\n", gv->recv_threads[i].name);
 | 
			
		||||
      GVERROR ("rtps_init: failed to start thread %s\n", gv->recv_threads[i].name);
 | 
			
		||||
      goto fail;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
| 
						 | 
				
			
			@ -872,18 +868,16 @@ int rtps_init (struct q_globals *gv)
 | 
			
		|||
  gv->thread_pool = NULL;
 | 
			
		||||
  gv->debmon = NULL;
 | 
			
		||||
 | 
			
		||||
  /* Print start time for referencing relative times in the remainder
 | 
			
		||||
   of the DDS_LOG. */
 | 
			
		||||
  /* Print start time for referencing relative times in the remainder of the DDS_LOG. */
 | 
			
		||||
  {
 | 
			
		||||
    int sec = (int) (gv->tstart.v / 1000000000);
 | 
			
		||||
    int usec = (int) (gv->tstart.v % 1000000000) / 1000;
 | 
			
		||||
    char str[DDSRT_RFC3339STRLEN];
 | 
			
		||||
    char str[DDSRT_RFC3339STRLEN+1];
 | 
			
		||||
    ddsrt_ctime(gv->tstart.v, str, sizeof(str));
 | 
			
		||||
    DDS_LOG(DDS_LC_CONFIG, "started at %d.06%d -- %s\n", sec, usec, str);
 | 
			
		||||
    GVLOG (DDS_LC_CONFIG, "started at %d.06%d -- %s\n", sec, usec, str);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /* Initialize thread pool */
 | 
			
		||||
 | 
			
		||||
  if (gv->config.tp_enable)
 | 
			
		||||
  {
 | 
			
		||||
    gv->thread_pool = ddsrt_thread_pool_new (gv->config.tp_threads, gv->config.tp_max_threads, 0, NULL);
 | 
			
		||||
| 
						 | 
				
			
			@ -927,14 +921,14 @@ int rtps_init (struct q_globals *gv)
 | 
			
		|||
  if (!find_own_ip (gv, gv->config.networkAddressString))
 | 
			
		||||
  {
 | 
			
		||||
    /* find_own_ip already logs a more informative error message */
 | 
			
		||||
    DDS_LOG(DDS_LC_CONFIG, "No network interface selected\n");
 | 
			
		||||
    GVLOG (DDS_LC_CONFIG, "No network interface selected\n");
 | 
			
		||||
    goto err_find_own_ip;
 | 
			
		||||
  }
 | 
			
		||||
  if (gv->config.allowMulticast)
 | 
			
		||||
  {
 | 
			
		||||
    if (!gv->interfaces[gv->selected_interface].mc_capable)
 | 
			
		||||
    {
 | 
			
		||||
      DDS_WARNING("selected interface is not multicast-capable: disabling multicast\n");
 | 
			
		||||
      GVWARNING ("selected interface is not multicast-capable: disabling multicast\n");
 | 
			
		||||
      gv->config.allowMulticast = AMC_FALSE;
 | 
			
		||||
      /* ensure discovery can work: firstly, that the process will be reachable on a "well-known" port
 | 
			
		||||
         number, and secondly, that the local interface's IP address gets added to the discovery
 | 
			
		||||
| 
						 | 
				
			
			@ -950,11 +944,11 @@ int rtps_init (struct q_globals *gv)
 | 
			
		|||
      if (gv->interfaces[gv->selected_interface].mc_flaky)
 | 
			
		||||
      {
 | 
			
		||||
        gv->config.allowMulticast = AMC_SPDP;
 | 
			
		||||
        DDS_LOG(DDS_LC_CONFIG, "presumed flaky multicast, use for SPDP only\n");
 | 
			
		||||
        GVLOG (DDS_LC_CONFIG, "presumed flaky multicast, use for SPDP only\n");
 | 
			
		||||
      }
 | 
			
		||||
      else
 | 
			
		||||
      {
 | 
			
		||||
        DDS_LOG(DDS_LC_CONFIG, "presumed robust multicast support, use for everything\n");
 | 
			
		||||
        GVLOG (DDS_LC_CONFIG, "presumed robust multicast support, use for everything\n");
 | 
			
		||||
        gv->config.allowMulticast = AMC_TRUE;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -973,24 +967,24 @@ int rtps_init (struct q_globals *gv)
 | 
			
		|||
  {
 | 
			
		||||
    char buf[DDSI_LOCSTRLEN];
 | 
			
		||||
    /* the "ownip", "extip" labels in the trace have been there for so long, that it seems worthwhile to retain them even though they need not be IP any longer */
 | 
			
		||||
    DDS_LOG(DDS_LC_CONFIG, "ownip: %s\n", ddsi_locator_to_string_no_port (gv, buf, sizeof(buf), &gv->ownloc));
 | 
			
		||||
    DDS_LOG(DDS_LC_CONFIG, "extip: %s\n", ddsi_locator_to_string_no_port (gv, buf, sizeof(buf), &gv->extloc));
 | 
			
		||||
    DDS_LOG(DDS_LC_CONFIG, "extmask: %s%s\n", ddsi_locator_to_string_no_port (gv, buf, sizeof(buf), &gv->extmask), gv->m_factory->m_kind != NN_LOCATOR_KIND_UDPv4 ? " (not applicable)" : "");
 | 
			
		||||
    DDS_LOG(DDS_LC_CONFIG, "networkid: 0x%lx\n", (unsigned long) gv->myNetworkId);
 | 
			
		||||
    DDS_LOG(DDS_LC_CONFIG, "SPDP MC: %s\n", ddsi_locator_to_string_no_port (gv, buf, sizeof(buf), &gv->loc_spdp_mc));
 | 
			
		||||
    DDS_LOG(DDS_LC_CONFIG, "default MC: %s\n", ddsi_locator_to_string_no_port (gv, buf, sizeof(buf), &gv->loc_default_mc));
 | 
			
		||||
    GVLOG (DDS_LC_CONFIG, "ownip: %s\n", ddsi_locator_to_string_no_port (gv, buf, sizeof(buf), &gv->ownloc));
 | 
			
		||||
    GVLOG (DDS_LC_CONFIG, "extip: %s\n", ddsi_locator_to_string_no_port (gv, buf, sizeof(buf), &gv->extloc));
 | 
			
		||||
    GVLOG (DDS_LC_CONFIG, "extmask: %s%s\n", ddsi_locator_to_string_no_port (gv, buf, sizeof(buf), &gv->extmask), gv->m_factory->m_kind != NN_LOCATOR_KIND_UDPv4 ? " (not applicable)" : "");
 | 
			
		||||
    GVLOG (DDS_LC_CONFIG, "networkid: 0x%lx\n", (unsigned long) gv->myNetworkId);
 | 
			
		||||
    GVLOG (DDS_LC_CONFIG, "SPDP MC: %s\n", ddsi_locator_to_string_no_port (gv, buf, sizeof(buf), &gv->loc_spdp_mc));
 | 
			
		||||
    GVLOG (DDS_LC_CONFIG, "default MC: %s\n", ddsi_locator_to_string_no_port (gv, buf, sizeof(buf), &gv->loc_default_mc));
 | 
			
		||||
#ifdef DDSI_INCLUDE_SSM
 | 
			
		||||
    DDS_LOG(DDS_LC_CONFIG, "SSM support included\n");
 | 
			
		||||
    GVLOG (DDS_LC_CONFIG, "SSM support included\n");
 | 
			
		||||
#endif
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (gv->ownloc.kind != gv->extloc.kind)
 | 
			
		||||
    DDS_FATAL("mismatch between network address kinds\n");
 | 
			
		||||
    DDS_FATAL ("mismatch between network address kinds\n");
 | 
			
		||||
 | 
			
		||||
#ifdef DDSI_INCLUDE_NETWORK_PARTITIONS
 | 
			
		||||
  /* Convert address sets in partition mappings from string to address sets */
 | 
			
		||||
  {
 | 
			
		||||
    const int port = gv->config.port_base + gv->config.port_dg * gv->config.domainId.value + gv->config.port_d2;
 | 
			
		||||
    const uint32_t port = gv->config.port_base + gv->config.port_dg * gv->config.domainId.value + gv->config.port_d2;
 | 
			
		||||
    struct config_networkpartition_listelem *np;
 | 
			
		||||
    for (np = gv->config.networkPartitions; np; np = np->next)
 | 
			
		||||
    {
 | 
			
		||||
| 
						 | 
				
			
			@ -1000,7 +994,7 @@ int rtps_init (struct q_globals *gv)
 | 
			
		|||
      int rc;
 | 
			
		||||
      snprintf (msgtag, slen, "%s%s", np->name, msgtag_fixed);
 | 
			
		||||
      np->as = new_addrset ();
 | 
			
		||||
      rc = add_addresses_to_addrset (gv, np->as, np->address_string, port, msgtag, 1);
 | 
			
		||||
      rc = add_addresses_to_addrset (gv, np->as, np->address_string, (int) port, msgtag, 1);
 | 
			
		||||
      ddsrt_free (msgtag);
 | 
			
		||||
      if (rc < 0)
 | 
			
		||||
        goto err_network_partition_addrset;
 | 
			
		||||
| 
						 | 
				
			
			@ -1015,7 +1009,7 @@ int rtps_init (struct q_globals *gv)
 | 
			
		|||
  if (q_security_plugin.new_decoder)
 | 
			
		||||
  {
 | 
			
		||||
    gv->recvSecurityCodec = (q_security_plugin.new_decoder) ();
 | 
			
		||||
    DDS_LOG(DDS_LC_CONFIG, "decoderset created\n");
 | 
			
		||||
    GVLOG (DDS_LC_CONFIG, "decoderset created\n");
 | 
			
		||||
  }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1050,8 +1044,8 @@ int rtps_init (struct q_globals *gv)
 | 
			
		|||
 | 
			
		||||
  ddsrt_mutex_init (&gv->lock);
 | 
			
		||||
  ddsrt_mutex_init (&gv->spdp_lock);
 | 
			
		||||
  gv->spdp_defrag = nn_defrag_new (NN_DEFRAG_DROP_OLDEST, gv->config.defrag_unreliable_maxsamples);
 | 
			
		||||
  gv->spdp_reorder = nn_reorder_new (NN_REORDER_MODE_ALWAYS_DELIVER, gv->config.primary_reorder_maxsamples, false);
 | 
			
		||||
  gv->spdp_defrag = nn_defrag_new (&gv->logconfig, NN_DEFRAG_DROP_OLDEST, gv->config.defrag_unreliable_maxsamples);
 | 
			
		||||
  gv->spdp_reorder = nn_reorder_new (&gv->logconfig, NN_REORDER_MODE_ALWAYS_DELIVER, gv->config.primary_reorder_maxsamples, false);
 | 
			
		||||
 | 
			
		||||
  gv->m_tkmap = ddsi_tkmap_new (gv);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1061,7 +1055,7 @@ int rtps_init (struct q_globals *gv)
 | 
			
		|||
    {
 | 
			
		||||
      if (make_uc_sockets (gv, &port_disc_uc, &port_data_uc, gv->config.participantIndex) < 0)
 | 
			
		||||
      {
 | 
			
		||||
        DDS_ERROR("rtps_init: failed to create unicast sockets for domain %"PRId32" participant %d\n", gv->config.domainId.value, gv->config.participantIndex);
 | 
			
		||||
        GVERROR ("rtps_init: failed to create unicast sockets for domain %"PRId32" participant %d\n", gv->config.domainId.value, gv->config.participantIndex);
 | 
			
		||||
        goto err_unicast_sockets;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -1069,7 +1063,7 @@ int rtps_init (struct q_globals *gv)
 | 
			
		|||
    {
 | 
			
		||||
      /* try to find a free one, and update gv->config.participantIndex */
 | 
			
		||||
      int ppid;
 | 
			
		||||
      DDS_LOG(DDS_LC_CONFIG, "rtps_init: trying to find a free participant index\n");
 | 
			
		||||
      GVLOG (DDS_LC_CONFIG, "rtps_init: trying to find a free participant index\n");
 | 
			
		||||
      for (ppid = 0; ppid <= gv->config.maxAutoParticipantIndex; ppid++)
 | 
			
		||||
      {
 | 
			
		||||
        int r = make_uc_sockets (gv, &port_disc_uc, &port_data_uc, ppid);
 | 
			
		||||
| 
						 | 
				
			
			@ -1079,13 +1073,13 @@ int rtps_init (struct q_globals *gv)
 | 
			
		|||
          continue;
 | 
			
		||||
        else /* Oops! */
 | 
			
		||||
        {
 | 
			
		||||
          DDS_ERROR("rtps_init: failed to create unicast sockets for domain %"PRId32" participant %d\n", gv->config.domainId.value, ppid);
 | 
			
		||||
          GVERROR ("rtps_init: failed to create unicast sockets for domain %"PRId32" participant %d\n", gv->config.domainId.value, ppid);
 | 
			
		||||
          goto err_unicast_sockets;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      if (ppid > gv->config.maxAutoParticipantIndex)
 | 
			
		||||
      {
 | 
			
		||||
        DDS_ERROR("rtps_init: failed to find a free participant index for domain %"PRId32"\n", gv->config.domainId.value);
 | 
			
		||||
        GVERROR ("rtps_init: failed to find a free participant index for domain %"PRId32"\n", gv->config.domainId.value);
 | 
			
		||||
        goto err_unicast_sockets;
 | 
			
		||||
      }
 | 
			
		||||
      gv->config.participantIndex = ppid;
 | 
			
		||||
| 
						 | 
				
			
			@ -1094,13 +1088,13 @@ int rtps_init (struct q_globals *gv)
 | 
			
		|||
    {
 | 
			
		||||
      assert(0);
 | 
			
		||||
    }
 | 
			
		||||
    DDS_LOG(DDS_LC_CONFIG, "rtps_init: uc ports: disc %"PRIu32" data %"PRIu32"\n", port_disc_uc, port_data_uc);
 | 
			
		||||
    GVLOG (DDS_LC_CONFIG, "rtps_init: uc ports: disc %"PRIu32" data %"PRIu32"\n", port_disc_uc, port_data_uc);
 | 
			
		||||
  }
 | 
			
		||||
  DDS_LOG(DDS_LC_CONFIG, "rtps_init: domainid %"PRId32" participantid %d\n", gv->config.domainId.value, gv->config.participantIndex);
 | 
			
		||||
  GVLOG (DDS_LC_CONFIG, "rtps_init: domainid %"PRId32" participantid %d\n", gv->config.domainId.value, gv->config.participantIndex);
 | 
			
		||||
 | 
			
		||||
  if (gv->config.pcap_file && *gv->config.pcap_file)
 | 
			
		||||
  {
 | 
			
		||||
    gv->pcap_fp = new_pcap_file (gv->config.pcap_file);
 | 
			
		||||
    gv->pcap_fp = new_pcap_file (&gv->logconfig, gv->config.pcap_file);
 | 
			
		||||
    if (gv->pcap_fp)
 | 
			
		||||
    {
 | 
			
		||||
      ddsrt_mutex_init (&gv->pcap_lock);
 | 
			
		||||
| 
						 | 
				
			
			@ -1116,7 +1110,7 @@ int rtps_init (struct q_globals *gv)
 | 
			
		|||
  if (gv->m_factory->m_connless)
 | 
			
		||||
  {
 | 
			
		||||
    if (!(gv->config.many_sockets_mode == MSM_NO_UNICAST && gv->config.allowMulticast))
 | 
			
		||||
      DDS_TRACE("Unicast Ports: discovery %"PRIu32" data %"PRIu32"\n", ddsi_conn_port (gv->disc_conn_uc), ddsi_conn_port (gv->data_conn_uc));
 | 
			
		||||
      GVTRACE ("Unicast Ports: discovery %"PRIu32" data %"PRIu32"\n", ddsi_conn_port (gv->disc_conn_uc), ddsi_conn_port (gv->data_conn_uc));
 | 
			
		||||
 | 
			
		||||
    if (gv->config.allowMulticast)
 | 
			
		||||
    {
 | 
			
		||||
| 
						 | 
				
			
			@ -1151,7 +1145,7 @@ int rtps_init (struct q_globals *gv)
 | 
			
		|||
      gv->listener = ddsi_factory_create_listener (gv->m_factory, gv->config.tcp_port, NULL);
 | 
			
		||||
      if (gv->listener == NULL || ddsi_listener_listen (gv->listener) != 0)
 | 
			
		||||
      {
 | 
			
		||||
        DDS_ERROR("Failed to create %s listener\n", gv->m_factory->m_typename);
 | 
			
		||||
        GVERROR ("Failed to create %s listener\n", gv->m_factory->m_typename);
 | 
			
		||||
        if (gv->listener)
 | 
			
		||||
          ddsi_listener_free(gv->listener);
 | 
			
		||||
        goto err_mc_conn;
 | 
			
		||||
| 
						 | 
				
			
			@ -1170,7 +1164,7 @@ int rtps_init (struct q_globals *gv)
 | 
			
		|||
  /* Create shared transmit connection */
 | 
			
		||||
 | 
			
		||||
  gv->tev_conn = gv->data_conn_uc;
 | 
			
		||||
  DDS_TRACE("Timed event transmit port: %d\n", (int) ddsi_conn_port (gv->tev_conn));
 | 
			
		||||
  GVTRACE ("Timed event transmit port: %d\n", (int) ddsi_conn_port (gv->tev_conn));
 | 
			
		||||
 | 
			
		||||
#ifdef DDSI_INCLUDE_NETWORK_CHANNELS
 | 
			
		||||
  {
 | 
			
		||||
| 
						 | 
				
			
			@ -1191,14 +1185,14 @@ int rtps_init (struct q_globals *gv)
 | 
			
		|||
        ddsi_tran_free_qos (qos);
 | 
			
		||||
        if (chptr->transmit_conn == NULL)
 | 
			
		||||
        {
 | 
			
		||||
          DDS_FATAL("failed to create transmit connection for channel %s\n", chptr->name);
 | 
			
		||||
          DDS_FATAL ("failed to create transmit connection for channel %s\n", chptr->name);
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      else
 | 
			
		||||
      {
 | 
			
		||||
        chptr->transmit_conn = gv->data_conn_uc;
 | 
			
		||||
      }
 | 
			
		||||
      DDS_TRACE("channel %s: transmit port %d\n", chptr->name, (int) ddsi_tran_port (chptr->transmit_conn));
 | 
			
		||||
      GVTRACE ("channel %s: transmit port %d\n", chptr->name, (int) ddsi_tran_port (chptr->transmit_conn));
 | 
			
		||||
 | 
			
		||||
#ifdef DDSI_INCLUDE_BANDWIDTH_LIMITING
 | 
			
		||||
      if (chptr->auxiliary_bandwidth_limit > 0 || lookup_thread_properties (tname))
 | 
			
		||||
| 
						 | 
				
			
			@ -1303,7 +1297,7 @@ err_mc_conn:
 | 
			
		|||
    ddsi_conn_free (gv->disc_conn_uc);
 | 
			
		||||
  if (gv->data_conn_uc != gv->disc_conn_uc)
 | 
			
		||||
    ddsi_conn_free (gv->data_conn_uc);
 | 
			
		||||
  free_group_membership(gv->mship);
 | 
			
		||||
  free_group_membership (gv->mship);
 | 
			
		||||
err_unicast_sockets:
 | 
			
		||||
  ddsi_tkmap_free (gv->m_tkmap);
 | 
			
		||||
  nn_reorder_free (gv->spdp_reorder);
 | 
			
		||||
| 
						 | 
				
			
			@ -1396,11 +1390,14 @@ int rtps_start (struct q_globals *gv)
 | 
			
		|||
  if (gv->listener)
 | 
			
		||||
  {
 | 
			
		||||
    create_thread (&gv->listen_ts, gv, "listen", (uint32_t (*) (void *)) listen_thread, gv->listener);
 | 
			
		||||
    /* FIXME: error handling */
 | 
			
		||||
  }
 | 
			
		||||
  if (gv->config.monitor_port >= 0)
 | 
			
		||||
  {
 | 
			
		||||
    gv->debmon = new_debug_monitor (gv, gv->config.monitor_port);
 | 
			
		||||
    /* FIXME: clean up */
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1680,5 +1677,5 @@ void rtps_fini (struct q_globals *gv)
 | 
			
		|||
 | 
			
		||||
  ddsi_serdatapool_free (gv->serpool);
 | 
			
		||||
  nn_xmsgpool_free (gv->xmsgpool);
 | 
			
		||||
  DDS_LOG(DDS_LC_CONFIG, "Finis.\n");
 | 
			
		||||
  GVLOG (DDS_LC_CONFIG, "Finis.\n");
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -56,7 +56,7 @@ void nn_lat_estim_update (struct nn_lat_estim *le, int64_t est)
 | 
			
		|||
    le->smoothed = (1.0f - alpha) * le->smoothed + alpha * med;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int nn_lat_estim_log (uint32_t logcat, const char *tag, const struct nn_lat_estim *le)
 | 
			
		||||
int nn_lat_estim_log (uint32_t logcat, const struct ddsrt_log_cfg *logcfg, const char *tag, const struct nn_lat_estim *le)
 | 
			
		||||
{
 | 
			
		||||
  if (le->smoothed == 0.0f)
 | 
			
		||||
    return 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -67,12 +67,12 @@ int nn_lat_estim_log (uint32_t logcat, const char *tag, const struct nn_lat_esti
 | 
			
		|||
    memcpy (tmp, le->window, sizeof (tmp));
 | 
			
		||||
    qsort (tmp, NN_LAT_ESTIM_MEDIAN_WINSZ, sizeof (tmp[0]), (int (*) (const void *, const void *)) cmpfloat);
 | 
			
		||||
    if (tag)
 | 
			
		||||
      DDS_LOG(logcat, " LAT(%s: %e {", tag, le->smoothed);
 | 
			
		||||
      DDS_CLOG (logcat, logcfg, " LAT(%s: %e {", tag, le->smoothed);
 | 
			
		||||
    else
 | 
			
		||||
      DDS_LOG(logcat, " LAT(%e {", le->smoothed);
 | 
			
		||||
      DDS_CLOG (logcat, logcfg, " LAT(%e {", le->smoothed);
 | 
			
		||||
    for (i = 0; i < NN_LAT_ESTIM_MEDIAN_WINSZ; i++)
 | 
			
		||||
      DDS_LOG(logcat, "%s%e", (i > 0) ? "," : "", tmp[i]);
 | 
			
		||||
    DDS_LOG(logcat, "})");
 | 
			
		||||
      DDS_CLOG (logcat, logcfg, "%s%e", (i > 0) ? "," : "", tmp[i]);
 | 
			
		||||
    DDS_CLOG (logcat, logcfg, "})");
 | 
			
		||||
    return 1;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -84,7 +84,7 @@ struct lease *lease_new (nn_etime_t texpire, dds_duration_t tdur, struct entity_
 | 
			
		|||
  struct lease *l;
 | 
			
		||||
  if ((l = ddsrt_malloc (sizeof (*l))) == NULL)
 | 
			
		||||
    return NULL;
 | 
			
		||||
  DDS_TRACE("lease_new(tdur %"PRId64" guid "PGUIDFMT") @ %p\n", tdur, PGUID (e->guid), (void *) l);
 | 
			
		||||
  EETRACE (e, "lease_new(tdur %"PRId64" guid "PGUIDFMT") @ %p\n", tdur, PGUID (e->guid), (void *) l);
 | 
			
		||||
  l->tdur = tdur;
 | 
			
		||||
  ddsrt_atomic_st64 (&l->tend, (uint64_t) texpire.v);
 | 
			
		||||
  l->tsched.v = TSCHED_NOT_ON_HEAP;
 | 
			
		||||
| 
						 | 
				
			
			@ -95,7 +95,7 @@ struct lease *lease_new (nn_etime_t texpire, dds_duration_t tdur, struct entity_
 | 
			
		|||
void lease_register (struct lease *l) /* FIXME: make lease admin struct */
 | 
			
		||||
{
 | 
			
		||||
  struct q_globals * const gv = l->entity->gv;
 | 
			
		||||
  DDS_TRACE("lease_register(l %p guid "PGUIDFMT")\n", (void *) l, PGUID (l->entity->guid));
 | 
			
		||||
  GVTRACE ("lease_register(l %p guid "PGUIDFMT")\n", (void *) l, PGUID (l->entity->guid));
 | 
			
		||||
  ddsrt_mutex_lock (&gv->leaseheap_lock);
 | 
			
		||||
  assert (l->tsched.v == TSCHED_NOT_ON_HEAP);
 | 
			
		||||
  int64_t tend = (int64_t) ddsrt_atomic_ld64 (&l->tend);
 | 
			
		||||
| 
						 | 
				
			
			@ -113,7 +113,7 @@ void lease_register (struct lease *l) /* FIXME: make lease admin struct */
 | 
			
		|||
void lease_free (struct lease *l)
 | 
			
		||||
{
 | 
			
		||||
  struct q_globals * const gv = l->entity->gv;
 | 
			
		||||
  DDS_TRACE("lease_free(l %p guid "PGUIDFMT")\n", (void *) l, PGUID (l->entity->guid));
 | 
			
		||||
  GVTRACE ("lease_free(l %p guid "PGUIDFMT")\n", (void *) l, PGUID (l->entity->guid));
 | 
			
		||||
  ddsrt_mutex_lock (&gv->leaseheap_lock);
 | 
			
		||||
  if (l->tsched.v != TSCHED_NOT_ON_HEAP)
 | 
			
		||||
    ddsrt_fibheap_delete (&lease_fhdef, &gv->leaseheap, l);
 | 
			
		||||
| 
						 | 
				
			
			@ -126,6 +126,7 @@ void lease_free (struct lease *l)
 | 
			
		|||
 | 
			
		||||
void lease_renew (struct lease *l, nn_etime_t tnowE)
 | 
			
		||||
{
 | 
			
		||||
  struct q_globals const * const gv = l->entity->gv;
 | 
			
		||||
  nn_etime_t tend_new = add_duration_to_etime (tnowE, l->tdur);
 | 
			
		||||
 | 
			
		||||
  /* do not touch tend if moving forward or if already expired */
 | 
			
		||||
| 
						 | 
				
			
			@ -136,16 +137,16 @@ void lease_renew (struct lease *l, nn_etime_t tnowE)
 | 
			
		|||
      return;
 | 
			
		||||
  } while (!ddsrt_atomic_cas64 (&l->tend, (uint64_t) tend, (uint64_t) tend_new.v));
 | 
			
		||||
 | 
			
		||||
  if ((dds_get_log_mask() & DDS_LC_TRACE))
 | 
			
		||||
  if (gv->logconfig.c.mask & DDS_LC_TRACE)
 | 
			
		||||
  {
 | 
			
		||||
    int32_t tsec, tusec;
 | 
			
		||||
    DDS_TRACE(" L(");
 | 
			
		||||
    GVTRACE (" L(");
 | 
			
		||||
    if (l->entity->guid.entityid.u == NN_ENTITYID_PARTICIPANT)
 | 
			
		||||
      DDS_TRACE(":%"PRIx32, l->entity->guid.entityid.u);
 | 
			
		||||
      GVTRACE (":%"PRIx32, l->entity->guid.entityid.u);
 | 
			
		||||
    else
 | 
			
		||||
      DDS_TRACE(""PGUIDFMT"", PGUID (l->entity->guid));
 | 
			
		||||
      GVTRACE (""PGUIDFMT"", PGUID (l->entity->guid));
 | 
			
		||||
    etime_to_sec_usec (&tsec, &tusec, tend_new);
 | 
			
		||||
    DDS_TRACE(" %"PRId32".%06"PRId32")", tsec, tusec);
 | 
			
		||||
    GVTRACE (" %"PRId32".%06"PRId32")", tsec, tusec);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -207,7 +208,7 @@ int64_t check_and_handle_lease_expiration (struct q_globals *gv, nn_etime_t tnow
 | 
			
		|||
      continue;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    DDS_LOG(DDS_LC_DISCOVERY, "lease expired: l %p guid "PGUIDFMT" tend %"PRId64" < now %"PRId64"\n", (void *) l, PGUID (g), tend, tnowE.v);
 | 
			
		||||
    GVLOGDISC ("lease expired: l %p guid "PGUIDFMT" tend %"PRId64" < now %"PRId64"\n", (void *) l, PGUID (g), tend, tnowE.v);
 | 
			
		||||
 | 
			
		||||
    /* If the proxy participant is relying on another participant for
 | 
			
		||||
       writing its discovery data (on the privileged participant,
 | 
			
		||||
| 
						 | 
				
			
			@ -240,8 +241,7 @@ int64_t check_and_handle_lease_expiration (struct q_globals *gv, nn_etime_t tnow
 | 
			
		|||
      if ((proxypp = ephash_lookup_proxy_participant_guid (gv->guid_hash, &g)) != NULL &&
 | 
			
		||||
          ephash_lookup_proxy_participant_guid (gv->guid_hash, &proxypp->privileged_pp_guid) != NULL)
 | 
			
		||||
      {
 | 
			
		||||
        DDS_LOG(DDS_LC_DISCOVERY, "but postponing because privileged pp "PGUIDFMT" is still live\n",
 | 
			
		||||
                PGUID (proxypp->privileged_pp_guid));
 | 
			
		||||
        GVLOGDISC ("but postponing because privileged pp "PGUIDFMT" is still live\n", PGUID (proxypp->privileged_pp_guid));
 | 
			
		||||
        l->tsched = add_duration_to_etime (tnowE, 200 * T_MILLISECOND);
 | 
			
		||||
        ddsrt_fibheap_insert (&lease_fhdef, &gv->leaseheap, l);
 | 
			
		||||
        continue;
 | 
			
		||||
| 
						 | 
				
			
			@ -283,19 +283,19 @@ int64_t check_and_handle_lease_expiration (struct q_globals *gv, nn_etime_t tnow
 | 
			
		|||
 | 
			
		||||
/******/
 | 
			
		||||
 | 
			
		||||
static void debug_print_rawdata (const char *msg, const void *data, size_t len)
 | 
			
		||||
static void debug_print_rawdata (const struct q_globals *gv, const char *msg, const void *data, size_t len)
 | 
			
		||||
{
 | 
			
		||||
  const unsigned char *c = data;
 | 
			
		||||
  size_t i;
 | 
			
		||||
  DDS_TRACE("%s<", msg);
 | 
			
		||||
  GVTRACE ("%s<", msg);
 | 
			
		||||
  for (i = 0; i < len; i++)
 | 
			
		||||
  {
 | 
			
		||||
    if (32 < c[i] && c[i] <= 127)
 | 
			
		||||
      DDS_TRACE("%s%c", (i > 0 && (i%4) == 0) ? " " : "", c[i]);
 | 
			
		||||
      GVTRACE ("%s%c", (i > 0 && (i%4) == 0) ? " " : "", c[i]);
 | 
			
		||||
    else
 | 
			
		||||
      DDS_TRACE("%s\\x%02x", (i > 0 && (i%4) == 0) ? " " : "", c[i]);
 | 
			
		||||
      GVTRACE ("%s\\x%02x", (i > 0 && (i%4) == 0) ? " " : "", c[i]);
 | 
			
		||||
  }
 | 
			
		||||
  DDS_TRACE(">");
 | 
			
		||||
  GVTRACE (">");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void handle_PMD (const struct receiver_state *rst, nn_wctime_t timestamp, uint32_t statusinfo, const void *vdata, uint32_t len)
 | 
			
		||||
| 
						 | 
				
			
			@ -304,32 +304,32 @@ void handle_PMD (const struct receiver_state *rst, nn_wctime_t timestamp, uint32
 | 
			
		|||
  const int bswap = (data->identifier == CDR_LE) ^ (DDSRT_ENDIAN == DDSRT_LITTLE_ENDIAN);
 | 
			
		||||
  struct proxy_participant *pp;
 | 
			
		||||
  nn_guid_t ppguid;
 | 
			
		||||
  DDS_TRACE(" PMD ST%x", statusinfo);
 | 
			
		||||
  RSTTRACE (" PMD ST%x", statusinfo);
 | 
			
		||||
  if (data->identifier != CDR_LE && data->identifier != CDR_BE)
 | 
			
		||||
  {
 | 
			
		||||
    DDS_TRACE(" PMD data->identifier %u !?\n", ntohs (data->identifier));
 | 
			
		||||
    RSTTRACE (" PMD data->identifier %u !?\n", ntohs (data->identifier));
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
  switch (statusinfo & (NN_STATUSINFO_DISPOSE | NN_STATUSINFO_UNREGISTER))
 | 
			
		||||
  {
 | 
			
		||||
    case 0:
 | 
			
		||||
      if (offsetof (ParticipantMessageData_t, value) > len - sizeof (struct CDRHeader))
 | 
			
		||||
        debug_print_rawdata (" SHORT1", data, len);
 | 
			
		||||
        debug_print_rawdata (rst->gv, " SHORT1", data, len);
 | 
			
		||||
      else
 | 
			
		||||
      {
 | 
			
		||||
        const ParticipantMessageData_t *pmd = (ParticipantMessageData_t *) (data + 1);
 | 
			
		||||
        nn_guid_prefix_t p = nn_ntoh_guid_prefix (pmd->participantGuidPrefix);
 | 
			
		||||
        uint32_t kind = ntohl (pmd->kind);
 | 
			
		||||
        uint32_t length = bswap ? bswap4u (pmd->length) : pmd->length;
 | 
			
		||||
        DDS_TRACE(" pp %"PRIx32":%"PRIx32":%"PRIx32" kind %u data %u", p.u[0], p.u[1], p.u[2], kind, length);
 | 
			
		||||
        RSTTRACE (" pp %"PRIx32":%"PRIx32":%"PRIx32" kind %u data %u", p.u[0], p.u[1], p.u[2], kind, length);
 | 
			
		||||
        if (len - sizeof (struct CDRHeader) - offsetof (ParticipantMessageData_t, value) < length)
 | 
			
		||||
          debug_print_rawdata (" SHORT2", pmd->value, len - sizeof (struct CDRHeader) - offsetof (ParticipantMessageData_t, value));
 | 
			
		||||
          debug_print_rawdata (rst->gv, " SHORT2", pmd->value, len - sizeof (struct CDRHeader) - offsetof (ParticipantMessageData_t, value));
 | 
			
		||||
        else
 | 
			
		||||
          debug_print_rawdata ("", pmd->value, length);
 | 
			
		||||
          debug_print_rawdata (rst->gv, "", pmd->value, length);
 | 
			
		||||
        ppguid.prefix = p;
 | 
			
		||||
        ppguid.entityid.u = NN_ENTITYID_PARTICIPANT;
 | 
			
		||||
        if ((pp = ephash_lookup_proxy_participant_guid (rst->gv->guid_hash, &ppguid)) == NULL)
 | 
			
		||||
          DDS_TRACE(" PPunknown");
 | 
			
		||||
          RSTTRACE (" PPunknown");
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
          /* Renew lease if arrival of this message didn't already do so, also renew the lease
 | 
			
		||||
| 
						 | 
				
			
			@ -347,17 +347,17 @@ void handle_PMD (const struct receiver_state *rst, nn_wctime_t timestamp, uint32
 | 
			
		|||
      /* Serialized key; BE or LE doesn't matter as both fields are
 | 
			
		||||
         defined as octets.  */
 | 
			
		||||
      if (len < sizeof (struct CDRHeader) + sizeof (nn_guid_prefix_t))
 | 
			
		||||
        debug_print_rawdata (" SHORT3", data, len);
 | 
			
		||||
        debug_print_rawdata (rst->gv, " SHORT3", data, len);
 | 
			
		||||
      else
 | 
			
		||||
      {
 | 
			
		||||
        ppguid.prefix = nn_ntoh_guid_prefix (*((nn_guid_prefix_t *) (data + 1)));
 | 
			
		||||
        ppguid.entityid.u = NN_ENTITYID_PARTICIPANT;
 | 
			
		||||
        if (delete_proxy_participant_by_guid (rst->gv, &ppguid, timestamp, 0) < 0)
 | 
			
		||||
          DDS_TRACE(" unknown");
 | 
			
		||||
          RSTTRACE (" unknown");
 | 
			
		||||
        else
 | 
			
		||||
          DDS_TRACE(" delete");
 | 
			
		||||
          RSTTRACE (" delete");
 | 
			
		||||
      }
 | 
			
		||||
      break;
 | 
			
		||||
  }
 | 
			
		||||
  DDS_TRACE("\n");
 | 
			
		||||
  RSTTRACE ("\n");
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -33,9 +33,9 @@
 | 
			
		|||
#include "dds/ddsi/ddsi_ipaddr.h"
 | 
			
		||||
#include "dds/ddsrt/avl.h"
 | 
			
		||||
 | 
			
		||||
static void print_sockerror (const char *msg)
 | 
			
		||||
static void print_sockerror (const struct ddsrt_log_cfg *logcfg, const char *msg)
 | 
			
		||||
{
 | 
			
		||||
  DDS_ERROR("SOCKET %s\n", msg);
 | 
			
		||||
  DDS_CERROR (logcfg, "SOCKET %s\n", msg);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint32_t locator_to_hopefully_unique_uint32 (const nn_locator_t *src)
 | 
			
		||||
| 
						 | 
				
			
			@ -53,45 +53,45 @@ uint32_t locator_to_hopefully_unique_uint32 (const nn_locator_t *src)
 | 
			
		|||
    ddsrt_md5_finish (&st, digest);
 | 
			
		||||
    memcpy (&id, digest, sizeof (id));
 | 
			
		||||
#else
 | 
			
		||||
    DDS_FATAL("IPv6 unavailable\n");
 | 
			
		||||
    DDS_FATAL ("IPv6 unavailable\n");
 | 
			
		||||
#endif
 | 
			
		||||
  }
 | 
			
		||||
  return id;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#ifdef DDSI_INCLUDE_NETWORK_CHANNELS
 | 
			
		||||
void set_socket_diffserv (ddsrt_socket_t sock, int diffserv)
 | 
			
		||||
void set_socket_diffserv (const struct ddsrt_log_cfg *logcfg, ddsrt_socket_t sock, int diffserv)
 | 
			
		||||
{
 | 
			
		||||
  if (ddsrt_setsockopt (sock, IPPROTO_IP, IP_TOS, (char*) &diffserv, sizeof (diffserv)) != DDS_RETCODE_OK)
 | 
			
		||||
  {
 | 
			
		||||
    print_sockerror ("IP_TOS");
 | 
			
		||||
    print_sockerror (logcfg, "IP_TOS");
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef SO_NOSIGPIPE
 | 
			
		||||
static void set_socket_nosigpipe (ddsrt_socket_t sock)
 | 
			
		||||
static void set_socket_nosigpipe (const struct ddsrt_log_cfg *logcfg, ddsrt_socket_t sock)
 | 
			
		||||
{
 | 
			
		||||
  int val = 1;
 | 
			
		||||
  if (ddsrt_setsockopt (sock, SOL_SOCKET, SO_NOSIGPIPE, (char*) &val, sizeof (val)) != DDS_RETCODE_OK)
 | 
			
		||||
  {
 | 
			
		||||
    print_sockerror ("SO_NOSIGPIPE");
 | 
			
		||||
    print_sockerror (logcfg, "SO_NOSIGPIPE");
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef TCP_NODELAY
 | 
			
		||||
static void set_socket_nodelay (ddsrt_socket_t sock)
 | 
			
		||||
static void set_socket_nodelay (const struct ddsrt_log_cfg *logcfg, ddsrt_socket_t sock)
 | 
			
		||||
{
 | 
			
		||||
  int val = 1;
 | 
			
		||||
  if (ddsrt_setsockopt (sock, IPPROTO_TCP, TCP_NODELAY, (char*) &val, sizeof (val)) != DDS_RETCODE_OK)
 | 
			
		||||
  {
 | 
			
		||||
    print_sockerror ("TCP_NODELAY");
 | 
			
		||||
    print_sockerror (logcfg, "TCP_NODELAY");
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
static int set_rcvbuf (ddsrt_socket_t socket, const struct config_maybe_uint32 *min_size)
 | 
			
		||||
static int set_rcvbuf (const struct ddsrt_log_cfg *logcfg, ddsrt_socket_t socket, const struct config_maybe_uint32 *min_size)
 | 
			
		||||
{
 | 
			
		||||
  uint32_t ReceiveBufferSize;
 | 
			
		||||
  socklen_t optlen = (socklen_t) sizeof (ReceiveBufferSize);
 | 
			
		||||
| 
						 | 
				
			
			@ -105,10 +105,10 @@ static int set_rcvbuf (ddsrt_socket_t socket, const struct config_maybe_uint32 *
 | 
			
		|||
    socket, SOL_SOCKET, SO_RCVBUF, (char *) &ReceiveBufferSize, &optlen);
 | 
			
		||||
  /* TCP/IP stack may not support SO_RCVBUF. */
 | 
			
		||||
  if (rc == DDS_RETCODE_BAD_PARAMETER) {
 | 
			
		||||
    DDS_LOG(DDS_LC_CONFIG, "cannot retrieve socket receive buffer size\n");
 | 
			
		||||
    DDS_CLOG (DDS_LC_CONFIG, logcfg, "cannot retrieve socket receive buffer size\n");
 | 
			
		||||
    return 0;
 | 
			
		||||
  } else if (rc != DDS_RETCODE_OK) {
 | 
			
		||||
    print_sockerror ("get SO_RCVBUF");
 | 
			
		||||
    print_sockerror (logcfg, "get SO_RCVBUF");
 | 
			
		||||
    return -2;
 | 
			
		||||
  }
 | 
			
		||||
  if (ReceiveBufferSize < socket_min_rcvbuf_size)
 | 
			
		||||
| 
						 | 
				
			
			@ -122,26 +122,25 @@ static int set_rcvbuf (ddsrt_socket_t socket, const struct config_maybe_uint32 *
 | 
			
		|||
       the option value back and check it is now set correctly. */
 | 
			
		||||
    if (ddsrt_getsockopt (socket, SOL_SOCKET, SO_RCVBUF, (char *) &ReceiveBufferSize, &optlen) != DDS_RETCODE_OK)
 | 
			
		||||
    {
 | 
			
		||||
      print_sockerror ("get SO_RCVBUF");
 | 
			
		||||
      print_sockerror (logcfg, "get SO_RCVBUF");
 | 
			
		||||
      return -2;
 | 
			
		||||
    }
 | 
			
		||||
    if (ReceiveBufferSize < socket_min_rcvbuf_size)
 | 
			
		||||
    {
 | 
			
		||||
      /* NN_ERROR does more than just DDS_ERROR(), hence the duplication */
 | 
			
		||||
      if (min_size->isdefault)
 | 
			
		||||
        DDS_LOG(DDS_LC_CONFIG, "failed to increase socket receive buffer size to %"PRIu32" bytes, continuing with %"PRIu32" bytes\n", socket_min_rcvbuf_size, ReceiveBufferSize);
 | 
			
		||||
      else
 | 
			
		||||
        DDS_ERROR("failed to increase socket receive buffer size to %"PRIu32" bytes, continuing with %"PRIu32" bytes\n", socket_min_rcvbuf_size, ReceiveBufferSize);
 | 
			
		||||
      DDS_CLOG (min_size->isdefault ? DDS_LC_CONFIG : DDS_LC_ERROR, logcfg,
 | 
			
		||||
                "failed to increase socket receive buffer size to %"PRIu32" bytes, continuing with %"PRIu32" bytes\n",
 | 
			
		||||
                socket_min_rcvbuf_size, ReceiveBufferSize);
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
      DDS_LOG(DDS_LC_CONFIG, "socket receive buffer size set to %"PRIu32" bytes\n", ReceiveBufferSize);
 | 
			
		||||
      DDS_CLOG (DDS_LC_CONFIG, logcfg, "socket receive buffer size set to %"PRIu32" bytes\n", ReceiveBufferSize);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int set_sndbuf (ddsrt_socket_t socket, uint32_t min_size)
 | 
			
		||||
static int set_sndbuf (const struct ddsrt_log_cfg *logcfg, ddsrt_socket_t socket, uint32_t min_size)
 | 
			
		||||
{
 | 
			
		||||
  unsigned SendBufferSize;
 | 
			
		||||
  socklen_t optlen = (socklen_t) sizeof(SendBufferSize);
 | 
			
		||||
| 
						 | 
				
			
			@ -149,10 +148,10 @@ static int set_sndbuf (ddsrt_socket_t socket, uint32_t min_size)
 | 
			
		|||
  rc = ddsrt_getsockopt(
 | 
			
		||||
    socket, SOL_SOCKET, SO_SNDBUF,(char *)&SendBufferSize, &optlen);
 | 
			
		||||
  if (rc == DDS_RETCODE_BAD_PARAMETER) {
 | 
			
		||||
    DDS_LOG(DDS_LC_CONFIG, "cannot retrieve socket send buffer size\n");
 | 
			
		||||
    DDS_CLOG (DDS_LC_CONFIG, logcfg, "cannot retrieve socket send buffer size\n");
 | 
			
		||||
    return 0;
 | 
			
		||||
  } else if (rc != DDS_RETCODE_OK) {
 | 
			
		||||
    print_sockerror ("get SO_SNDBUF");
 | 
			
		||||
    print_sockerror (logcfg, "get SO_SNDBUF");
 | 
			
		||||
    return -2;
 | 
			
		||||
  }
 | 
			
		||||
  if (SendBufferSize < min_size )
 | 
			
		||||
| 
						 | 
				
			
			@ -161,14 +160,14 @@ static int set_sndbuf (ddsrt_socket_t socket, uint32_t min_size)
 | 
			
		|||
    SendBufferSize = min_size;
 | 
			
		||||
    if (ddsrt_setsockopt (socket, SOL_SOCKET, SO_SNDBUF, (const char *)&SendBufferSize, sizeof (SendBufferSize)) != DDS_RETCODE_OK)
 | 
			
		||||
    {
 | 
			
		||||
      print_sockerror ("SO_SNDBUF");
 | 
			
		||||
      print_sockerror (logcfg, "SO_SNDBUF");
 | 
			
		||||
      return -2;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int maybe_set_dont_route (ddsrt_socket_t socket, const struct config *config)
 | 
			
		||||
static int maybe_set_dont_route (const struct ddsrt_log_cfg *logcfg, ddsrt_socket_t socket, const struct config *config)
 | 
			
		||||
{
 | 
			
		||||
  if (config->dontRoute)
 | 
			
		||||
  {
 | 
			
		||||
| 
						 | 
				
			
			@ -178,7 +177,7 @@ static int maybe_set_dont_route (ddsrt_socket_t socket, const struct config *con
 | 
			
		|||
      unsigned ipv6Flag = 1;
 | 
			
		||||
      if (ddsrt_setsockopt (socket, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &ipv6Flag, sizeof (ipv6Flag)) != DDS_RETCODE_OK)
 | 
			
		||||
      {
 | 
			
		||||
        print_sockerror ("IPV6_UNICAST_HOPS");
 | 
			
		||||
        print_sockerror (logcfg, "IPV6_UNICAST_HOPS");
 | 
			
		||||
        return -2;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -189,7 +188,7 @@ static int maybe_set_dont_route (ddsrt_socket_t socket, const struct config *con
 | 
			
		|||
      int one = 1;
 | 
			
		||||
      if (ddsrt_setsockopt (socket, SOL_SOCKET, SO_DONTROUTE, (char *) &one, sizeof (one)) != DDS_RETCODE_OK)
 | 
			
		||||
      {
 | 
			
		||||
        print_sockerror ("SO_DONTROUTE");
 | 
			
		||||
        print_sockerror (logcfg, "SO_DONTROUTE");
 | 
			
		||||
        return -2;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -197,7 +196,7 @@ static int maybe_set_dont_route (ddsrt_socket_t socket, const struct config *con
 | 
			
		|||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int set_reuse_options (ddsrt_socket_t socket)
 | 
			
		||||
static int set_reuse_options (const struct ddsrt_log_cfg *logcfg, ddsrt_socket_t socket)
 | 
			
		||||
{
 | 
			
		||||
  /* Set REUSEADDR (if available on platform) for
 | 
			
		||||
     multicast sockets, leave unicast sockets alone. */
 | 
			
		||||
| 
						 | 
				
			
			@ -205,10 +204,10 @@ static int set_reuse_options (ddsrt_socket_t socket)
 | 
			
		|||
  dds_return_t rc = ddsrt_setsockopt (
 | 
			
		||||
      socket, SOL_SOCKET, SO_REUSEADDR, (char *) &one, sizeof (one));
 | 
			
		||||
  if (rc == DDS_RETCODE_BAD_PARAMETER) {
 | 
			
		||||
    DDS_LOG(DDS_LC_CONFIG, "cannot enable address reuse on socket\n");
 | 
			
		||||
    DDS_CLOG (DDS_LC_CONFIG, logcfg, "cannot enable address reuse on socket\n");
 | 
			
		||||
    return 0;
 | 
			
		||||
  } else if (rc != DDS_RETCODE_OK) {
 | 
			
		||||
    print_sockerror ("SO_REUSEADDR");
 | 
			
		||||
    print_sockerror (logcfg, "SO_REUSEADDR");
 | 
			
		||||
    return -2;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -244,7 +243,7 @@ static int bind_socket (ddsrt_socket_t socket, unsigned short port, const struct
 | 
			
		|||
  }
 | 
			
		||||
  if (rc != DDS_RETCODE_OK && rc != DDS_RETCODE_PRECONDITION_NOT_MET)
 | 
			
		||||
  {
 | 
			
		||||
    print_sockerror ("bind");
 | 
			
		||||
    print_sockerror (&gv->logconfig, "bind");
 | 
			
		||||
  }
 | 
			
		||||
  return (rc == DDS_RETCODE_OK) ? 0 : -1;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -257,18 +256,18 @@ static int set_mc_options_transmit_ipv6 (ddsrt_socket_t socket, const struct q_g
 | 
			
		|||
  unsigned loop;
 | 
			
		||||
  if (ddsrt_setsockopt (socket, IPPROTO_IPV6, IPV6_MULTICAST_IF, &interfaceNo, sizeof (interfaceNo)) != DDS_RETCODE_OK)
 | 
			
		||||
  {
 | 
			
		||||
    print_sockerror ("IPV6_MULTICAST_IF");
 | 
			
		||||
    print_sockerror (&gv->logconfig, "IPV6_MULTICAST_IF");
 | 
			
		||||
    return -2;
 | 
			
		||||
  }
 | 
			
		||||
  if (ddsrt_setsockopt (socket, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, (char *) &ttl, sizeof (ttl)) != DDS_RETCODE_OK)
 | 
			
		||||
  {
 | 
			
		||||
    print_sockerror ("IPV6_MULTICAST_HOPS");
 | 
			
		||||
    print_sockerror (&gv->logconfig, "IPV6_MULTICAST_HOPS");
 | 
			
		||||
    return -2;
 | 
			
		||||
  }
 | 
			
		||||
  loop = (unsigned) !!gv->config.enableMulticastLoopback;
 | 
			
		||||
  if (ddsrt_setsockopt (socket, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &loop, sizeof (loop)) != DDS_RETCODE_OK)
 | 
			
		||||
  {
 | 
			
		||||
    print_sockerror ("IPV6_MULTICAST_LOOP");
 | 
			
		||||
    print_sockerror (&gv->logconfig, "IPV6_MULTICAST_LOOP");
 | 
			
		||||
    return -2;
 | 
			
		||||
  }
 | 
			
		||||
  return 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -302,19 +301,19 @@ static int set_mc_options_transmit_ipv4 (ddsrt_socket_t socket, const struct q_g
 | 
			
		|||
  }
 | 
			
		||||
  if (ret != DDS_RETCODE_OK)
 | 
			
		||||
  {
 | 
			
		||||
    print_sockerror ("IP_MULTICAST_IF");
 | 
			
		||||
    print_sockerror (&gv->logconfig, "IP_MULTICAST_IF");
 | 
			
		||||
    return -2;
 | 
			
		||||
  }
 | 
			
		||||
  if (ddsrt_setsockopt (socket, IPPROTO_IP, IP_MULTICAST_TTL, (char *) &ttl, sizeof (ttl)) != DDS_RETCODE_OK)
 | 
			
		||||
  {
 | 
			
		||||
    print_sockerror ("IP_MULICAST_TTL");
 | 
			
		||||
    print_sockerror (&gv->logconfig, "IP_MULICAST_TTL");
 | 
			
		||||
    return -2;
 | 
			
		||||
  }
 | 
			
		||||
  loop = (unsigned char) gv->config.enableMulticastLoopback;
 | 
			
		||||
 | 
			
		||||
  if (ddsrt_setsockopt (socket, IPPROTO_IP, IP_MULTICAST_LOOP, &loop, sizeof (loop)) != DDS_RETCODE_OK)
 | 
			
		||||
  {
 | 
			
		||||
    print_sockerror ("IP_MULTICAST_LOOP");
 | 
			
		||||
    print_sockerror (&gv->logconfig, "IP_MULTICAST_LOOP");
 | 
			
		||||
    return -2;
 | 
			
		||||
  }
 | 
			
		||||
  return 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -363,20 +362,20 @@ int make_socket (ddsrt_socket_t *sock, uint16_t port, bool stream, bool reuse, c
 | 
			
		|||
 | 
			
		||||
  if (ret != DDS_RETCODE_OK)
 | 
			
		||||
  {
 | 
			
		||||
    print_sockerror ("socket");
 | 
			
		||||
    print_sockerror (&gv->logconfig, "socket");
 | 
			
		||||
    return rc;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (port && reuse && ((rc = set_reuse_options (*sock)) < 0))
 | 
			
		||||
  if (port && reuse && ((rc = set_reuse_options (&gv->logconfig, *sock)) < 0))
 | 
			
		||||
  {
 | 
			
		||||
    goto fail;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if
 | 
			
		||||
  (
 | 
			
		||||
    (rc = set_rcvbuf (*sock, &gv->config.socket_min_rcvbuf_size) < 0) ||
 | 
			
		||||
    (rc = set_sndbuf (*sock, gv->config.socket_min_sndbuf_size) < 0) ||
 | 
			
		||||
    ((rc = maybe_set_dont_route (*sock, &gv->config)) < 0) ||
 | 
			
		||||
    (rc = set_rcvbuf (&gv->logconfig, *sock, &gv->config.socket_min_rcvbuf_size) < 0) ||
 | 
			
		||||
    (rc = set_sndbuf (&gv->logconfig, *sock, gv->config.socket_min_sndbuf_size) < 0) ||
 | 
			
		||||
    ((rc = maybe_set_dont_route (&gv->logconfig, *sock, &gv->config)) < 0) ||
 | 
			
		||||
    ((rc = bind_socket (*sock, port, gv)) < 0)
 | 
			
		||||
  )
 | 
			
		||||
  {
 | 
			
		||||
| 
						 | 
				
			
			@ -394,12 +393,12 @@ int make_socket (ddsrt_socket_t *sock, uint16_t port, bool stream, bool reuse, c
 | 
			
		|||
  if (stream)
 | 
			
		||||
  {
 | 
			
		||||
#ifdef SO_NOSIGPIPE
 | 
			
		||||
    set_socket_nosigpipe (*sock);
 | 
			
		||||
    set_socket_nosigpipe (&gv->logconfig, *sock);
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef TCP_NODELAY
 | 
			
		||||
    if (gv->config.tcp_nodelay)
 | 
			
		||||
    {
 | 
			
		||||
      set_socket_nodelay (*sock);
 | 
			
		||||
      set_socket_nodelay (&gv->logconfig, *sock);
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
  }
 | 
			
		||||
| 
						 | 
				
			
			@ -447,13 +446,13 @@ int find_own_ip (struct q_globals *gv, const char *requested_address)
 | 
			
		|||
  int selected_idx = -1;
 | 
			
		||||
  char addrbuf[DDSI_LOCSTRLEN];
 | 
			
		||||
 | 
			
		||||
  DDS_LOG(DDS_LC_CONFIG, "interfaces:");
 | 
			
		||||
  GVLOG (DDS_LC_CONFIG, "interfaces:");
 | 
			
		||||
 | 
			
		||||
  {
 | 
			
		||||
    int ret;
 | 
			
		||||
    ret = ddsi_enumerate_interfaces(gv->m_factory, gv->config.transport_selector, &ifa_root);
 | 
			
		||||
    if (ret < 0) {
 | 
			
		||||
      DDS_ERROR("ddsi_enumerate_interfaces(%s): %d\n", gv->m_factory->m_typename, ret);
 | 
			
		||||
      GVERROR ("ddsi_enumerate_interfaces(%s): %d\n", gv->m_factory->m_typename, ret);
 | 
			
		||||
      return 0;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
| 
						 | 
				
			
			@ -468,15 +467,15 @@ int find_own_ip (struct q_globals *gv, const char *requested_address)
 | 
			
		|||
    ddsrt_strlcpy(if_name, ifa->name, sizeof(if_name));
 | 
			
		||||
 | 
			
		||||
    if (strcmp (if_name, last_if_name))
 | 
			
		||||
      DDS_LOG(DDS_LC_CONFIG, "%s%s", sep, if_name);
 | 
			
		||||
      GVLOG (DDS_LC_CONFIG, "%s%s", sep, if_name);
 | 
			
		||||
    ddsrt_strlcpy(last_if_name, if_name, sizeof(last_if_name));
 | 
			
		||||
 | 
			
		||||
    /* interface must be up */
 | 
			
		||||
    if ((ifa->flags & IFF_UP) == 0) {
 | 
			
		||||
      DDS_LOG(DDS_LC_CONFIG, " (interface down)");
 | 
			
		||||
      GVLOG (DDS_LC_CONFIG, " (interface down)");
 | 
			
		||||
      continue;
 | 
			
		||||
    } else if (ddsrt_sockaddr_isunspecified(ifa->addr)) {
 | 
			
		||||
      DDS_LOG(DDS_LC_CONFIG, " (address unspecified)");
 | 
			
		||||
      GVLOG (DDS_LC_CONFIG, " (address unspecified)");
 | 
			
		||||
      continue;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -508,11 +507,11 @@ int find_own_ip (struct q_globals *gv, const char *requested_address)
 | 
			
		|||
      ddsi_ipaddr_to_loc(&gv->interfaces[gv->n_interfaces].loc, ifa->addr, gv->m_factory->m_kind);
 | 
			
		||||
    }
 | 
			
		||||
    ddsi_locator_to_string_no_port(gv, addrbuf, sizeof(addrbuf), &gv->interfaces[gv->n_interfaces].loc);
 | 
			
		||||
    DDS_LOG(DDS_LC_CONFIG, " %s(", addrbuf);
 | 
			
		||||
    GVLOG (DDS_LC_CONFIG, " %s(", addrbuf);
 | 
			
		||||
 | 
			
		||||
    if (!(ifa->flags & IFF_MULTICAST) && multicast_override (if_name, &gv->config))
 | 
			
		||||
    {
 | 
			
		||||
      DDS_LOG(DDS_LC_CONFIG, "assume-mc:");
 | 
			
		||||
      GVLOG (DDS_LC_CONFIG, "assume-mc:");
 | 
			
		||||
      ifa->flags |= IFF_MULTICAST;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -555,7 +554,7 @@ int find_own_ip (struct q_globals *gv, const char *requested_address)
 | 
			
		|||
        q += 2;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    DDS_LOG(DDS_LC_CONFIG, "q%d)", q);
 | 
			
		||||
    GVLOG (DDS_LC_CONFIG, "q%d)", q);
 | 
			
		||||
    if (q == quality) {
 | 
			
		||||
      maxq_list[maxq_count] = gv->n_interfaces;
 | 
			
		||||
      maxq_strlen += 2 + strlen (if_name);
 | 
			
		||||
| 
						 | 
				
			
			@ -584,7 +583,7 @@ int find_own_ip (struct q_globals *gv, const char *requested_address)
 | 
			
		|||
    gv->interfaces[gv->n_interfaces].name = ddsrt_strdup (if_name);
 | 
			
		||||
    gv->n_interfaces++;
 | 
			
		||||
  }
 | 
			
		||||
  DDS_LOG(DDS_LC_CONFIG, "\n");
 | 
			
		||||
  GVLOG (DDS_LC_CONFIG, "\n");
 | 
			
		||||
  ddsrt_freeifaddrs (ifa_root);
 | 
			
		||||
 | 
			
		||||
  if (requested_address == NULL)
 | 
			
		||||
| 
						 | 
				
			
			@ -599,15 +598,15 @@ int find_own_ip (struct q_globals *gv, const char *requested_address)
 | 
			
		|||
      p = 0;
 | 
			
		||||
      for (i = 0; i < maxq_count && (size_t) p < maxq_strlen; i++)
 | 
			
		||||
        p += snprintf (names + p, maxq_strlen - (size_t) p, ", %s", gv->interfaces[maxq_list[i]].name);
 | 
			
		||||
      DDS_WARNING("using network interface %s (%s) selected arbitrarily from: %s\n",
 | 
			
		||||
                   gv->interfaces[idx].name, addrbuf, names + 2);
 | 
			
		||||
      GVWARNING ("using network interface %s (%s) selected arbitrarily from: %s\n",
 | 
			
		||||
                 gv->interfaces[idx].name, addrbuf, names + 2);
 | 
			
		||||
      ddsrt_free (names);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (maxq_count > 0)
 | 
			
		||||
      selected_idx = maxq_list[0];
 | 
			
		||||
    else
 | 
			
		||||
      DDS_ERROR("failed to determine default own IP address\n");
 | 
			
		||||
      GVERROR ("failed to determine default own IP address\n");
 | 
			
		||||
  }
 | 
			
		||||
  else
 | 
			
		||||
  {
 | 
			
		||||
| 
						 | 
				
			
			@ -654,7 +653,7 @@ int find_own_ip (struct q_globals *gv, const char *requested_address)
 | 
			
		|||
    if (i < gv->n_interfaces)
 | 
			
		||||
      selected_idx = i;
 | 
			
		||||
    else
 | 
			
		||||
      DDS_ERROR("%s: does not match an available interface\n", gv->config.networkAddressString);
 | 
			
		||||
      GVERROR ("%s: does not match an available interface\n", gv->config.networkAddressString);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (selected_idx < 0)
 | 
			
		||||
| 
						 | 
				
			
			@ -676,8 +675,8 @@ int find_own_ip (struct q_globals *gv, const char *requested_address)
 | 
			
		|||
      gv->ipv6_link_local = 0;
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
    DDS_LOG(DDS_LC_CONFIG, "selected interface: %s (index %u)\n",
 | 
			
		||||
            gv->interfaces[selected_idx].name, gv->interfaceNo);
 | 
			
		||||
    GVLOG (DDS_LC_CONFIG, "selected interface: %s (index %u)\n",
 | 
			
		||||
           gv->interfaces[selected_idx].name, gv->interfaceNo);
 | 
			
		||||
 | 
			
		||||
    return 1;
 | 
			
		||||
  }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -77,7 +77,7 @@ static const ipv4_hdr_t ipv4_hdr_template = {
 | 
			
		|||
#define IPV4_HDR_SIZE 20
 | 
			
		||||
#define UDP_HDR_SIZE 8
 | 
			
		||||
 | 
			
		||||
FILE *new_pcap_file (const char *name)
 | 
			
		||||
FILE *new_pcap_file (const struct ddsrt_log_cfg *logcfg, const char *name)
 | 
			
		||||
{
 | 
			
		||||
  DDSRT_WARNING_MSVC_OFF(4996);
 | 
			
		||||
  FILE *fp;
 | 
			
		||||
| 
						 | 
				
			
			@ -85,7 +85,7 @@ FILE *new_pcap_file (const char *name)
 | 
			
		|||
 | 
			
		||||
  if ((fp = fopen (name, "wb")) == NULL)
 | 
			
		||||
  {
 | 
			
		||||
    DDS_WARNING ("packet capture disabled: file %s could not be opened for writing\n", name);
 | 
			
		||||
    DDS_CWARNING (logcfg, "packet capture disabled: file %s could not be opened for writing\n", name);
 | 
			
		||||
    return NULL;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -131,7 +131,7 @@ struct piddesc {
 | 
			
		|||
  dds_return_t (*deser_validate_xform) (void * __restrict dst, const struct dd * __restrict dd);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void log_octetseq (uint32_t cat, uint32_t n, const unsigned char *xs);
 | 
			
		||||
static void log_octetseq (uint32_t cat, const struct ddsrt_log_cfg *logcfg, uint32_t n, const unsigned char *xs);
 | 
			
		||||
static dds_return_t validate_history_qospolicy (const dds_history_qospolicy_t *q);
 | 
			
		||||
static dds_return_t validate_resource_limits_qospolicy (const dds_resource_limits_qospolicy_t *q);
 | 
			
		||||
static dds_return_t validate_history_and_resource_limits (const dds_history_qospolicy_t *qh, const dds_resource_limits_qospolicy_t *qr);
 | 
			
		||||
| 
						 | 
				
			
			@ -140,7 +140,7 @@ static dds_return_t validate_durability_service_qospolicy_acceptzero (const dds_
 | 
			
		|||
static dds_return_t do_locator (nn_locators_t *ls, uint64_t *present, uint64_t wanted, uint64_t fl, const struct dd *dd, const struct ddsi_tran_factory *factory);
 | 
			
		||||
static dds_return_t final_validation_qos (const dds_qos_t *dest, nn_protocol_version_t protocol_version, nn_vendorid_t vendorid, bool *dursvc_accepted_allzero, bool strict);
 | 
			
		||||
static int partitions_equal (const dds_partition_qospolicy_t *a, const dds_partition_qospolicy_t *b);
 | 
			
		||||
static dds_return_t nn_xqos_valid_strictness (const dds_qos_t *xqos, bool strict);
 | 
			
		||||
static dds_return_t nn_xqos_valid_strictness (const struct ddsrt_log_cfg *logcfg, const dds_qos_t *xqos, bool strict);
 | 
			
		||||
 | 
			
		||||
static size_t align4size (size_t x)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -1459,7 +1459,7 @@ void nn_plist_unalias (nn_plist_t *plist)
 | 
			
		|||
  plist_or_xqos_unalias (plist, 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static dds_return_t nn_xqos_valid_strictness (const dds_qos_t *xqos, bool strict)
 | 
			
		||||
static dds_return_t nn_xqos_valid_strictness (const struct ddsrt_log_cfg *logcfg, const dds_qos_t *xqos, bool strict)
 | 
			
		||||
{
 | 
			
		||||
  dds_return_t ret;
 | 
			
		||||
  if (piddesc_unalias[0] == NULL)
 | 
			
		||||
| 
						 | 
				
			
			@ -1481,7 +1481,7 @@ static dds_return_t nn_xqos_valid_strictness (const dds_qos_t *xqos, bool strict
 | 
			
		|||
          ret = entry->op.f.valid (xqos, srcoff);
 | 
			
		||||
        if (ret < 0)
 | 
			
		||||
        {
 | 
			
		||||
          DDS_LOG (DDS_LC_PLIST, "nn_xqos_valid: %s invalid\n", entry->name);
 | 
			
		||||
          DDS_CLOG (DDS_LC_PLIST, logcfg, "nn_xqos_valid: %s invalid\n", entry->name);
 | 
			
		||||
          return ret;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
| 
						 | 
				
			
			@ -1489,14 +1489,14 @@ static dds_return_t nn_xqos_valid_strictness (const dds_qos_t *xqos, bool strict
 | 
			
		|||
  }
 | 
			
		||||
  if ((ret = final_validation_qos (xqos, (nn_protocol_version_t) { RTPS_MAJOR, RTPS_MINOR }, NN_VENDORID_ECLIPSE, NULL, strict)) < 0)
 | 
			
		||||
  {
 | 
			
		||||
    DDS_LOG (DDS_LC_PLIST, "nn_xqos_valid: final validation failed\n");
 | 
			
		||||
    DDS_CLOG (DDS_LC_PLIST, logcfg, "nn_xqos_valid: final validation failed\n");
 | 
			
		||||
  }
 | 
			
		||||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
dds_return_t nn_xqos_valid (const dds_qos_t *xqos)
 | 
			
		||||
dds_return_t nn_xqos_valid (const struct ddsrt_log_cfg *logcfg, const dds_qos_t *xqos)
 | 
			
		||||
{
 | 
			
		||||
  return nn_xqos_valid_strictness (xqos, true);
 | 
			
		||||
  return nn_xqos_valid_strictness (logcfg, xqos, true);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint64_t nn_xqos_delta (const dds_qos_t *x, const dds_qos_t *y, uint64_t mask)
 | 
			
		||||
| 
						 | 
				
			
			@ -1885,7 +1885,7 @@ static dds_return_t return_unrecognized_pid (nn_plist_t *plist, nn_parameterid_t
 | 
			
		|||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static dds_return_t init_one_parameter (nn_plist_t *plist, nn_ipaddress_params_tmp_t *dest_tmp, uint64_t pwanted, uint64_t qwanted, uint16_t pid, const struct dd *dd, ddsi_tran_factory_t factory)
 | 
			
		||||
static dds_return_t init_one_parameter (nn_plist_t *plist, nn_ipaddress_params_tmp_t *dest_tmp, uint64_t pwanted, uint64_t qwanted, uint16_t pid, const struct dd *dd, ddsi_tran_factory_t factory, const ddsrt_log_cfg_t *logcfg)
 | 
			
		||||
{
 | 
			
		||||
  /* special-cased ipv4address and port, because they have state beyond that what gets
 | 
			
		||||
     passed into the generic code */
 | 
			
		||||
| 
						 | 
				
			
			@ -1922,10 +1922,10 @@ static dds_return_t init_one_parameter (nn_plist_t *plist, nn_ipaddress_params_t
 | 
			
		|||
  assert (pid_without_flags (pid) == pid_without_flags (entry->pid));
 | 
			
		||||
  if (pid != entry->pid)
 | 
			
		||||
  {
 | 
			
		||||
    DDS_LOG (DDS_LC_ERROR, "error processing parameter list (vendor %u.%u, version %u.%u): pid %"PRIx16" mapped to pid %"PRIx16"\n",
 | 
			
		||||
             dd->vendorid.id[0], dd->vendorid.id[1],
 | 
			
		||||
             dd->protocol_version.major, dd->protocol_version.minor,
 | 
			
		||||
             pid, entry->pid);
 | 
			
		||||
    DDS_CERROR (logcfg, "error processing parameter list (vendor %u.%u, version %u.%u): pid %"PRIx16" mapped to pid %"PRIx16"\n",
 | 
			
		||||
                dd->vendorid.id[0], dd->vendorid.id[1],
 | 
			
		||||
                dd->protocol_version.major, dd->protocol_version.minor,
 | 
			
		||||
                pid, entry->pid);
 | 
			
		||||
    return return_unrecognized_pid (plist, pid);
 | 
			
		||||
  }
 | 
			
		||||
  assert (pid != PID_PAD);
 | 
			
		||||
| 
						 | 
				
			
			@ -1949,10 +1949,10 @@ static dds_return_t init_one_parameter (nn_plist_t *plist, nn_ipaddress_params_t
 | 
			
		|||
     memory if deserialized repeatedly */
 | 
			
		||||
  if ((*flagset.present & entry->present_flag) && !(entry->flags & PDF_ALLOWMULTI))
 | 
			
		||||
  {
 | 
			
		||||
    DDS_LOG (DDS_LC_WARNING, "invalid parameter list (vendor %u.%u, version %u.%u): pid %"PRIx16" (%s) multiply defined\n",
 | 
			
		||||
             dd->vendorid.id[0], dd->vendorid.id[1],
 | 
			
		||||
             dd->protocol_version.major, dd->protocol_version.minor,
 | 
			
		||||
             pid, entry->name);
 | 
			
		||||
    DDS_CWARNING (logcfg, "invalid parameter list (vendor %u.%u, version %u.%u): pid %"PRIx16" (%s) multiply defined\n",
 | 
			
		||||
                  dd->vendorid.id[0], dd->vendorid.id[1],
 | 
			
		||||
                  dd->protocol_version.major, dd->protocol_version.minor,
 | 
			
		||||
                  pid, entry->name);
 | 
			
		||||
    return DDS_RETCODE_BAD_PARAMETER;
 | 
			
		||||
  }
 | 
			
		||||
  if (!(flagset.wanted & entry->present_flag))
 | 
			
		||||
| 
						 | 
				
			
			@ -1977,12 +1977,12 @@ static dds_return_t init_one_parameter (nn_plist_t *plist, nn_ipaddress_params_t
 | 
			
		|||
    ret = entry->deser_validate_xform (dst, dd);
 | 
			
		||||
  if (ret < 0)
 | 
			
		||||
  {
 | 
			
		||||
    DDS_LOG (DDS_LC_WARNING, "invalid parameter list (vendor %u.%u, version %u.%u): pid %"PRIx16" (%s) invalid, input = ",
 | 
			
		||||
             dd->vendorid.id[0], dd->vendorid.id[1],
 | 
			
		||||
             dd->protocol_version.major, dd->protocol_version.minor,
 | 
			
		||||
             pid, entry->name);
 | 
			
		||||
    log_octetseq (DDS_LC_WARNING, (uint32_t) dd->bufsz, dd->buf);
 | 
			
		||||
    DDS_LOG (DDS_LC_WARNING, "\n");
 | 
			
		||||
    DDS_CWARNING (logcfg, "invalid parameter list (vendor %u.%u, version %u.%u): pid %"PRIx16" (%s) invalid, input = ",
 | 
			
		||||
                  dd->vendorid.id[0], dd->vendorid.id[1],
 | 
			
		||||
                  dd->protocol_version.major, dd->protocol_version.minor,
 | 
			
		||||
                  pid, entry->name);
 | 
			
		||||
    log_octetseq (DDS_LC_WARNING, logcfg, (uint32_t) dd->bufsz, dd->buf);
 | 
			
		||||
    DDS_CWARNING (logcfg, "\n");
 | 
			
		||||
  }
 | 
			
		||||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -2135,14 +2135,14 @@ dds_return_t nn_plist_init_frommsg (nn_plist_t *dest, char **nextafterplist, uin
 | 
			
		|||
#endif
 | 
			
		||||
      break;
 | 
			
		||||
    default:
 | 
			
		||||
      DDS_WARNING ("plist(vendor %u.%u): unknown encoding (%d)\n",
 | 
			
		||||
                   src->vendorid.id[0], src->vendorid.id[1], src->encoding);
 | 
			
		||||
      DDS_CWARNING (src->logconfig, "plist(vendor %u.%u): unknown encoding (%d)\n",
 | 
			
		||||
                    src->vendorid.id[0], src->vendorid.id[1], src->encoding);
 | 
			
		||||
      return DDS_RETCODE_BAD_PARAMETER;
 | 
			
		||||
  }
 | 
			
		||||
  nn_plist_init_empty (dest);
 | 
			
		||||
  dest_tmp.present = 0;
 | 
			
		||||
 | 
			
		||||
  DDS_LOG(DDS_LC_PLIST, "NN_PLIST_INIT (bswap %d)\n", dd.bswap);
 | 
			
		||||
  DDS_CLOG (DDS_LC_PLIST, src->logconfig, "NN_PLIST_INIT (bswap %d)\n", dd.bswap);
 | 
			
		||||
 | 
			
		||||
  pl = src->buf;
 | 
			
		||||
  while (pl + sizeof (nn_parameter_t) <= src->buf + src->bufsz)
 | 
			
		||||
| 
						 | 
				
			
			@ -2160,7 +2160,7 @@ dds_return_t nn_plist_init_frommsg (nn_plist_t *dest, char **nextafterplist, uin
 | 
			
		|||
    {
 | 
			
		||||
      /* Sentinel terminates list, the length is ignored, DDSI 9.4.2.11. */
 | 
			
		||||
      bool dursvc_accepted_allzero;
 | 
			
		||||
      DDS_LOG(DDS_LC_PLIST, "%4"PRIx32" PID %"PRIx16"\n", (uint32_t) (pl - src->buf), pid);
 | 
			
		||||
      DDS_CLOG (DDS_LC_PLIST, src->logconfig, "%4"PRIx32" PID %"PRIx16"\n", (uint32_t) (pl - src->buf), pid);
 | 
			
		||||
      if ((res = final_validation (dest, src->protocol_version, src->vendorid, &dursvc_accepted_allzero, src->strict)) < 0)
 | 
			
		||||
      {
 | 
			
		||||
        nn_plist_fini (dest);
 | 
			
		||||
| 
						 | 
				
			
			@ -2180,32 +2180,32 @@ dds_return_t nn_plist_init_frommsg (nn_plist_t *dest, char **nextafterplist, uin
 | 
			
		|||
    }
 | 
			
		||||
    if (length > src->bufsz - sizeof (*par) - (uint32_t) (pl - src->buf))
 | 
			
		||||
    {
 | 
			
		||||
      DDS_WARNING("plist(vendor %u.%u): parameter length %"PRIu16" out of bounds\n",
 | 
			
		||||
                  src->vendorid.id[0], src->vendorid.id[1], length);
 | 
			
		||||
      DDS_CWARNING (src->logconfig, "plist(vendor %u.%u): parameter length %"PRIu16" out of bounds\n",
 | 
			
		||||
                    src->vendorid.id[0], src->vendorid.id[1], length);
 | 
			
		||||
      nn_plist_fini (dest);
 | 
			
		||||
      return DDS_RETCODE_BAD_PARAMETER;
 | 
			
		||||
    }
 | 
			
		||||
    if ((length % 4) != 0) /* DDSI 9.4.2.11 */
 | 
			
		||||
    {
 | 
			
		||||
      DDS_WARNING("plist(vendor %u.%u): parameter length %"PRIu16" mod 4 != 0\n",
 | 
			
		||||
                  src->vendorid.id[0], src->vendorid.id[1], length);
 | 
			
		||||
      DDS_CWARNING (src->logconfig, "plist(vendor %u.%u): parameter length %"PRIu16" mod 4 != 0\n",
 | 
			
		||||
                    src->vendorid.id[0], src->vendorid.id[1], length);
 | 
			
		||||
      nn_plist_fini (dest);
 | 
			
		||||
      return DDS_RETCODE_BAD_PARAMETER;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (dds_get_log_mask() & DDS_LC_PLIST)
 | 
			
		||||
    if (src->logconfig->c.mask & DDS_LC_PLIST)
 | 
			
		||||
    {
 | 
			
		||||
      DDS_LOG(DDS_LC_PLIST, "%4"PRIx32" PID %"PRIx16" len %"PRIu16" ", (uint32_t) (pl - src->buf), pid, length);
 | 
			
		||||
      log_octetseq(DDS_LC_PLIST, length, (const unsigned char *) (par + 1));
 | 
			
		||||
      DDS_LOG(DDS_LC_PLIST, "\n");
 | 
			
		||||
      DDS_CLOG (DDS_LC_PLIST, src->logconfig, "%4"PRIx32" PID %"PRIx16" len %"PRIu16" ", (uint32_t) (pl - src->buf), pid, length);
 | 
			
		||||
      log_octetseq (DDS_LC_PLIST, src->logconfig, length, (const unsigned char *) (par + 1));
 | 
			
		||||
      DDS_CLOG (DDS_LC_PLIST, src->logconfig, "\n");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    dd.buf = (const unsigned char *) (par + 1);
 | 
			
		||||
    dd.bufsz = length;
 | 
			
		||||
    if ((res = init_one_parameter (dest, &dest_tmp, pwanted, qwanted, pid, &dd, src->factory)) < 0)
 | 
			
		||||
    if ((res = init_one_parameter (dest, &dest_tmp, pwanted, qwanted, pid, &dd, src->factory, src->logconfig)) < 0)
 | 
			
		||||
    {
 | 
			
		||||
      /* make sure we print a trace message on error */
 | 
			
		||||
      DDS_TRACE("plist(vendor %u.%u): failed at pid=%"PRIx16"\n", src->vendorid.id[0], src->vendorid.id[1], pid);
 | 
			
		||||
      DDS_CTRACE (src->logconfig, "plist(vendor %u.%u): failed at pid=%"PRIx16"\n", src->vendorid.id[0], src->vendorid.id[1], pid);
 | 
			
		||||
      nn_plist_fini (dest);
 | 
			
		||||
      return res;
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -2213,8 +2213,8 @@ dds_return_t nn_plist_init_frommsg (nn_plist_t *dest, char **nextafterplist, uin
 | 
			
		|||
  }
 | 
			
		||||
  /* If we get here, that means we reached the end of the message
 | 
			
		||||
     without encountering a sentinel. That is an error */
 | 
			
		||||
  DDS_WARNING("plist(vendor %u.%u): invalid parameter list: sentinel missing\n",
 | 
			
		||||
              src->vendorid.id[0], src->vendorid.id[1]);
 | 
			
		||||
  DDS_CWARNING (src->logconfig, "plist(vendor %u.%u): invalid parameter list: sentinel missing\n",
 | 
			
		||||
                src->vendorid.id[0], src->vendorid.id[1]);
 | 
			
		||||
  nn_plist_fini (dest);
 | 
			
		||||
  return DDS_RETCODE_BAD_PARAMETER;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -2262,11 +2262,11 @@ unsigned char *nn_plist_quickscan (struct nn_rsample_info *dest, const struct nn
 | 
			
		|||
#endif
 | 
			
		||||
      break;
 | 
			
		||||
    default:
 | 
			
		||||
      DDS_WARNING("plist(vendor %u.%u): quickscan: unknown encoding (%d)\n",
 | 
			
		||||
                  src->vendorid.id[0], src->vendorid.id[1], src->encoding);
 | 
			
		||||
      DDS_CWARNING (src->logconfig, "plist(vendor %u.%u): quickscan: unknown encoding (%d)\n",
 | 
			
		||||
                    src->vendorid.id[0], src->vendorid.id[1], src->encoding);
 | 
			
		||||
      return NULL;
 | 
			
		||||
  }
 | 
			
		||||
  DDS_LOG(DDS_LC_PLIST, "NN_PLIST_QUICKSCAN (bswap %d)\n", dest->bswap);
 | 
			
		||||
  DDS_CLOG (DDS_LC_PLIST, src->logconfig, "NN_PLIST_QUICKSCAN (bswap %d)\n", dest->bswap);
 | 
			
		||||
  pl = src->buf;
 | 
			
		||||
  while (pl + sizeof (nn_parameter_t) <= src->buf + src->bufsz)
 | 
			
		||||
  {
 | 
			
		||||
| 
						 | 
				
			
			@ -2280,14 +2280,14 @@ unsigned char *nn_plist_quickscan (struct nn_rsample_info *dest, const struct nn
 | 
			
		|||
      return (unsigned char *) pl;
 | 
			
		||||
    if (length > src->bufsz - (size_t)(pl - src->buf))
 | 
			
		||||
    {
 | 
			
		||||
      DDS_WARNING("plist(vendor %u.%u): quickscan: parameter length %"PRIu16" out of bounds\n",
 | 
			
		||||
                  src->vendorid.id[0], src->vendorid.id[1], length);
 | 
			
		||||
      DDS_CWARNING (src->logconfig, "plist(vendor %u.%u): quickscan: parameter length %"PRIu16" out of bounds\n",
 | 
			
		||||
                    src->vendorid.id[0], src->vendorid.id[1], length);
 | 
			
		||||
      return NULL;
 | 
			
		||||
    }
 | 
			
		||||
    if ((length % 4) != 0) /* DDSI 9.4.2.11 */
 | 
			
		||||
    {
 | 
			
		||||
      DDS_WARNING("plist(vendor %u.%u): quickscan: parameter length %"PRIu16" mod 4 != 0\n",
 | 
			
		||||
                  src->vendorid.id[0], src->vendorid.id[1], length);
 | 
			
		||||
      DDS_CWARNING (src->logconfig, "plist(vendor %u.%u): quickscan: parameter length %"PRIu16" mod 4 != 0\n",
 | 
			
		||||
                    src->vendorid.id[0], src->vendorid.id[1], length);
 | 
			
		||||
      return NULL;
 | 
			
		||||
    }
 | 
			
		||||
    switch (pid)
 | 
			
		||||
| 
						 | 
				
			
			@ -2297,8 +2297,8 @@ unsigned char *nn_plist_quickscan (struct nn_rsample_info *dest, const struct nn
 | 
			
		|||
      case PID_STATUSINFO:
 | 
			
		||||
        if (length < 4)
 | 
			
		||||
        {
 | 
			
		||||
          DDS_TRACE("plist(vendor %u.%u): quickscan(PID_STATUSINFO): buffer too small\n",
 | 
			
		||||
                    src->vendorid.id[0], src->vendorid.id[1]);
 | 
			
		||||
          DDS_CTRACE (src->logconfig, "plist(vendor %u.%u): quickscan(PID_STATUSINFO): buffer too small\n",
 | 
			
		||||
                      src->vendorid.id[0], src->vendorid.id[1]);
 | 
			
		||||
          return NULL;
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
| 
						 | 
				
			
			@ -2314,7 +2314,7 @@ unsigned char *nn_plist_quickscan (struct nn_rsample_info *dest, const struct nn
 | 
			
		|||
      case PID_KEYHASH:
 | 
			
		||||
        break;
 | 
			
		||||
      default:
 | 
			
		||||
        DDS_LOG(DDS_LC_PLIST, "(pid=%"PRIx16" complex_qos=1)", pid);
 | 
			
		||||
        DDS_CLOG (DDS_LC_PLIST, src->logconfig, "(pid=%"PRIx16" complex_qos=1)", pid);
 | 
			
		||||
        dest->complex_qos = 1;
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -2322,8 +2322,8 @@ unsigned char *nn_plist_quickscan (struct nn_rsample_info *dest, const struct nn
 | 
			
		|||
  }
 | 
			
		||||
  /* If we get here, that means we reached the end of the message
 | 
			
		||||
     without encountering a sentinel. That is an error */
 | 
			
		||||
  DDS_WARNING("plist(vendor %u.%u): quickscan: invalid parameter list: sentinel missing\n",
 | 
			
		||||
              src->vendorid.id[0], src->vendorid.id[1]);
 | 
			
		||||
  DDS_CWARNING (src->logconfig, "plist(vendor %u.%u): quickscan: invalid parameter list: sentinel missing\n",
 | 
			
		||||
                src->vendorid.id[0], src->vendorid.id[1]);
 | 
			
		||||
  return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -2670,7 +2670,7 @@ static uint32_t isprint_runlen (uint32_t n, const unsigned char *xs)
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void log_octetseq (uint32_t cat, uint32_t n, const unsigned char *xs)
 | 
			
		||||
static void log_octetseq (uint32_t cat, const struct ddsrt_log_cfg *logcfg, uint32_t n, const unsigned char *xs)
 | 
			
		||||
{
 | 
			
		||||
  uint32_t i = 0;
 | 
			
		||||
  while (i < n)
 | 
			
		||||
| 
						 | 
				
			
			@ -2678,7 +2678,7 @@ static void log_octetseq (uint32_t cat, uint32_t n, const unsigned char *xs)
 | 
			
		|||
    uint32_t m = isprint_runlen (n - i, xs);
 | 
			
		||||
    if (m >= 4 || (i == 0 && m == n))
 | 
			
		||||
    {
 | 
			
		||||
      DDS_LOG (cat, "%s\"%*.*s\"", i == 0 ? "" : ",", m, m, xs);
 | 
			
		||||
      DDS_CLOG (cat, logcfg, "%s\"%*.*s\"", i == 0 ? "" : ",", m, m, xs);
 | 
			
		||||
      xs += m;
 | 
			
		||||
      i += m;
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -2688,23 +2688,19 @@ static void log_octetseq (uint32_t cat, uint32_t n, const unsigned char *xs)
 | 
			
		|||
        m = 1;
 | 
			
		||||
      while (m--)
 | 
			
		||||
      {
 | 
			
		||||
        DDS_LOG (cat, "%s%u", i == 0 ? "" : ",", *xs++);
 | 
			
		||||
        DDS_CLOG (cat, logcfg, "%s%u", i == 0 ? "" : ",", *xs++);
 | 
			
		||||
        i++;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void nn_log_xqos (uint32_t cat, const dds_qos_t *xqos)
 | 
			
		||||
void nn_log_xqos (uint32_t cat, const struct ddsrt_log_cfg *logcfg, const dds_qos_t *xqos)
 | 
			
		||||
{
 | 
			
		||||
  uint64_t p = xqos->present;
 | 
			
		||||
  const char *prefix = "";
 | 
			
		||||
#define LOGB0(fmt_) DDS_LOG(cat, "%s" fmt_, prefix)
 | 
			
		||||
#define LOGB1(fmt_, arg0_) DDS_LOG(cat, "%s" fmt_, prefix, arg0_)
 | 
			
		||||
#define LOGB2(fmt_, arg0_, arg1_) DDS_LOG(cat, "%s" fmt_, prefix, arg0_, arg1_)
 | 
			
		||||
#define LOGB3(fmt_, arg0_, arg1_, arg2_) DDS_LOG(cat, "%s" fmt_, prefix, arg0_, arg1_, arg2_)
 | 
			
		||||
#define LOGB4(fmt_, arg0_, arg1_, arg2_, arg3_) DDS_LOG(cat, "%s" fmt_, prefix, arg0_, arg1_, arg2_, arg3_)
 | 
			
		||||
#define LOGB5(fmt_, arg0_, arg1_, arg2_, arg3_, arg4_) DDS_LOG(cat, "%s" fmt_, prefix, arg0_, arg1_, arg2_, arg3_, arg4_)
 | 
			
		||||
#define LOGB0(fmt_) DDS_CLOG (cat, logcfg, "%s" fmt_, prefix)
 | 
			
		||||
#define LOGB1(fmt_, ...) DDS_CLOG (cat, logcfg, "%s" fmt_, prefix, __VA_ARGS__)
 | 
			
		||||
#define DO(name_, body_) do { if (p & QP_##name_) { { body_ } prefix = ","; } } while (0)
 | 
			
		||||
 | 
			
		||||
#define FMT_DUR "%"PRId64".%09"PRId32
 | 
			
		||||
| 
						 | 
				
			
			@ -2712,58 +2708,58 @@ void nn_log_xqos (uint32_t cat, const dds_qos_t *xqos)
 | 
			
		|||
 | 
			
		||||
  DO (TOPIC_NAME, { LOGB1 ("topic=%s", xqos->topic_name); });
 | 
			
		||||
  DO (TYPE_NAME, { LOGB1 ("type=%s", xqos->type_name); });
 | 
			
		||||
  DO (PRESENTATION, { LOGB3 ("presentation=%d:%u:%u", xqos->presentation.access_scope, xqos->presentation.coherent_access, xqos->presentation.ordered_access); });
 | 
			
		||||
  DO (PRESENTATION, { LOGB1 ("presentation=%d:%u:%u", xqos->presentation.access_scope, xqos->presentation.coherent_access, xqos->presentation.ordered_access); });
 | 
			
		||||
  DO (PARTITION, {
 | 
			
		||||
      LOGB0 ("partition={");
 | 
			
		||||
      for (uint32_t i = 0; i < xqos->partition.n; i++) {
 | 
			
		||||
        DDS_LOG(cat, "%s%s", (i == 0) ? "" : ",", xqos->partition.strs[i]);
 | 
			
		||||
        DDS_CLOG (cat, logcfg, "%s%s", (i == 0) ? "" : ",", xqos->partition.strs[i]);
 | 
			
		||||
      }
 | 
			
		||||
      DDS_LOG(cat, "}");
 | 
			
		||||
      DDS_CLOG (cat, logcfg, "}");
 | 
			
		||||
    });
 | 
			
		||||
  DO (GROUP_DATA, {
 | 
			
		||||
    LOGB1 ("group_data=%"PRIu32"<", xqos->group_data.length);
 | 
			
		||||
    log_octetseq (cat, xqos->group_data.length, xqos->group_data.value);
 | 
			
		||||
    DDS_LOG(cat, ">");
 | 
			
		||||
    log_octetseq (cat, logcfg, xqos->group_data.length, xqos->group_data.value);
 | 
			
		||||
    DDS_CLOG (cat, logcfg, ">");
 | 
			
		||||
  });
 | 
			
		||||
  DO (TOPIC_DATA, {
 | 
			
		||||
    LOGB1 ("topic_data=%"PRIu32"<", xqos->topic_data.length);
 | 
			
		||||
    log_octetseq (cat, xqos->topic_data.length, xqos->topic_data.value);
 | 
			
		||||
    DDS_LOG(cat, ">");
 | 
			
		||||
    log_octetseq (cat, logcfg, xqos->topic_data.length, xqos->topic_data.value);
 | 
			
		||||
    DDS_CLOG(cat, logcfg, ">");
 | 
			
		||||
  });
 | 
			
		||||
  DO (DURABILITY, { LOGB1 ("durability=%d", xqos->durability.kind); });
 | 
			
		||||
  DO (DURABILITY_SERVICE, {
 | 
			
		||||
      LOGB0 ("durability_service=");
 | 
			
		||||
      DDS_LOG(cat, FMT_DUR, PRINTARG_DUR (xqos->durability_service.service_cleanup_delay));
 | 
			
		||||
      DDS_LOG(cat, ":{%u:%"PRId32"}", xqos->durability_service.history.kind, xqos->durability_service.history.depth);
 | 
			
		||||
      DDS_LOG(cat, ":{%"PRId32":%"PRId32":%"PRId32"}", xqos->durability_service.resource_limits.max_samples, xqos->durability_service.resource_limits.max_instances, xqos->durability_service.resource_limits.max_samples_per_instance);
 | 
			
		||||
      DDS_CLOG(cat, logcfg, FMT_DUR, PRINTARG_DUR (xqos->durability_service.service_cleanup_delay));
 | 
			
		||||
      DDS_CLOG(cat, logcfg, ":{%u:%"PRId32"}", xqos->durability_service.history.kind, xqos->durability_service.history.depth);
 | 
			
		||||
      DDS_CLOG(cat, logcfg, ":{%"PRId32":%"PRId32":%"PRId32"}", xqos->durability_service.resource_limits.max_samples, xqos->durability_service.resource_limits.max_instances, xqos->durability_service.resource_limits.max_samples_per_instance);
 | 
			
		||||
    });
 | 
			
		||||
  DO (DEADLINE, { LOGB1 ("deadline="FMT_DUR, PRINTARG_DUR (xqos->deadline.deadline)); });
 | 
			
		||||
  DO (LATENCY_BUDGET, { LOGB1 ("latency_budget="FMT_DUR, PRINTARG_DUR (xqos->latency_budget.duration)); });
 | 
			
		||||
  DO (LIVELINESS, { LOGB2 ("liveliness=%d:"FMT_DUR, xqos->liveliness.kind, PRINTARG_DUR (xqos->liveliness.lease_duration)); });
 | 
			
		||||
  DO (RELIABILITY, { LOGB2 ("reliability=%d:"FMT_DUR, xqos->reliability.kind, PRINTARG_DUR (xqos->reliability.max_blocking_time)); });
 | 
			
		||||
  DO (LIVELINESS, { LOGB1 ("liveliness=%d:"FMT_DUR, xqos->liveliness.kind, PRINTARG_DUR (xqos->liveliness.lease_duration)); });
 | 
			
		||||
  DO (RELIABILITY, { LOGB1 ("reliability=%d:"FMT_DUR, xqos->reliability.kind, PRINTARG_DUR (xqos->reliability.max_blocking_time)); });
 | 
			
		||||
  DO (DESTINATION_ORDER, { LOGB1 ("destination_order=%d", xqos->destination_order.kind); });
 | 
			
		||||
  DO (HISTORY, { LOGB2 ("history=%d:%"PRId32, xqos->history.kind, xqos->history.depth); });
 | 
			
		||||
  DO (RESOURCE_LIMITS, { LOGB3 ("resource_limits=%"PRId32":%"PRId32":%"PRId32, xqos->resource_limits.max_samples, xqos->resource_limits.max_instances, xqos->resource_limits.max_samples_per_instance); });
 | 
			
		||||
  DO (HISTORY, { LOGB1 ("history=%d:%"PRId32, xqos->history.kind, xqos->history.depth); });
 | 
			
		||||
  DO (RESOURCE_LIMITS, { LOGB1 ("resource_limits=%"PRId32":%"PRId32":%"PRId32, xqos->resource_limits.max_samples, xqos->resource_limits.max_instances, xqos->resource_limits.max_samples_per_instance); });
 | 
			
		||||
  DO (TRANSPORT_PRIORITY, { LOGB1 ("transport_priority=%"PRId32, xqos->transport_priority.value); });
 | 
			
		||||
  DO (LIFESPAN, { LOGB1 ("lifespan="FMT_DUR, PRINTARG_DUR (xqos->lifespan.duration)); });
 | 
			
		||||
  DO (USER_DATA, {
 | 
			
		||||
    LOGB1 ("user_data=%"PRIu32"<", xqos->user_data.length);
 | 
			
		||||
    log_octetseq (cat, xqos->user_data.length, xqos->user_data.value);
 | 
			
		||||
    DDS_LOG(cat, ">");
 | 
			
		||||
    log_octetseq (cat, logcfg, xqos->user_data.length, xqos->user_data.value);
 | 
			
		||||
    DDS_CLOG (cat, logcfg, ">");
 | 
			
		||||
  });
 | 
			
		||||
  DO (OWNERSHIP, { LOGB1 ("ownership=%d", xqos->ownership.kind); });
 | 
			
		||||
  DO (OWNERSHIP_STRENGTH, { LOGB1 ("ownership_strength=%"PRId32, xqos->ownership_strength.value); });
 | 
			
		||||
  DO (TIME_BASED_FILTER, { LOGB1 ("time_based_filter="FMT_DUR, PRINTARG_DUR (xqos->time_based_filter.minimum_separation)); });
 | 
			
		||||
  DO (PRISMTECH_READER_DATA_LIFECYCLE, { LOGB2 ("reader_data_lifecycle="FMT_DUR":"FMT_DUR, PRINTARG_DUR (xqos->reader_data_lifecycle.autopurge_nowriter_samples_delay), PRINTARG_DUR (xqos->reader_data_lifecycle.autopurge_disposed_samples_delay)); });
 | 
			
		||||
  DO (PRISMTECH_READER_DATA_LIFECYCLE, { LOGB1 ("reader_data_lifecycle="FMT_DUR":"FMT_DUR, PRINTARG_DUR (xqos->reader_data_lifecycle.autopurge_nowriter_samples_delay), PRINTARG_DUR (xqos->reader_data_lifecycle.autopurge_disposed_samples_delay)); });
 | 
			
		||||
  DO (PRISMTECH_WRITER_DATA_LIFECYCLE, {
 | 
			
		||||
    LOGB1 ("writer_data_lifecycle={%u}", xqos->writer_data_lifecycle.autodispose_unregistered_instances); });
 | 
			
		||||
  DO (PRISMTECH_READER_LIFESPAN, { LOGB2 ("reader_lifespan={%u,"FMT_DUR"}", xqos->reader_lifespan.use_lifespan, PRINTARG_DUR (xqos->reader_lifespan.duration)); });
 | 
			
		||||
  DO (PRISMTECH_READER_LIFESPAN, { LOGB1 ("reader_lifespan={%u,"FMT_DUR"}", xqos->reader_lifespan.use_lifespan, PRINTARG_DUR (xqos->reader_lifespan.duration)); });
 | 
			
		||||
  DO (PRISMTECH_SUBSCRIPTION_KEYS, {
 | 
			
		||||
    LOGB1 ("subscription_keys={%u,{", xqos->subscription_keys.use_key_list);
 | 
			
		||||
    for (uint32_t i = 0; i < xqos->subscription_keys.key_list.n; i++) {
 | 
			
		||||
      DDS_LOG(cat, "%s%s", (i == 0) ? "" : ",", xqos->subscription_keys.key_list.strs[i]);
 | 
			
		||||
      DDS_CLOG (cat, logcfg, "%s%s", (i == 0) ? "" : ",", xqos->subscription_keys.key_list.strs[i]);
 | 
			
		||||
    }
 | 
			
		||||
    DDS_LOG(cat, "}}");
 | 
			
		||||
    DDS_CLOG (cat, logcfg, "}}");
 | 
			
		||||
  });
 | 
			
		||||
  DO (PRISMTECH_ENTITY_FACTORY, { LOGB1 ("entity_factory=%u", xqos->entity_factory.autoenable_created_entities); });
 | 
			
		||||
  DO (CYCLONE_IGNORELOCAL, { LOGB1 ("ignorelocal=%u", xqos->ignorelocal.value); });
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							| 
						 | 
				
			
			@ -154,7 +154,7 @@ static struct thread_state1 *lazy_create_thread_state (ddsrt_thread_t self)
 | 
			
		|||
    ddsrt_init ();
 | 
			
		||||
    ts1->extTid = self;
 | 
			
		||||
    ts1->tid = self;
 | 
			
		||||
    DDS_TRACE ("started application thread %s\n", name);
 | 
			
		||||
    DDS_LOG (DDS_LC_TRACE, "started application thread %s\n", name);
 | 
			
		||||
    ddsrt_thread_cleanup_push (&cleanup_thread_state, NULL);
 | 
			
		||||
  }
 | 
			
		||||
  ddsrt_mutex_unlock (&thread_states.lock);
 | 
			
		||||
| 
						 | 
				
			
			@ -185,7 +185,9 @@ static uint32_t create_thread_wrapper (void *ptr)
 | 
			
		|||
{
 | 
			
		||||
  uint32_t ret;
 | 
			
		||||
  struct thread_context *ctx = ptr;
 | 
			
		||||
  DDS_TRACE ("started new thread %"PRIdTID": %s\n", ddsrt_gettid (), ctx->self->name);
 | 
			
		||||
  struct q_globals const * const gv = ddsrt_atomic_ldvoidp (&ctx->self->gv);
 | 
			
		||||
  if (gv)
 | 
			
		||||
    GVTRACE ("started new thread %"PRIdTID": %s\n", ddsrt_gettid (), ctx->self->name);
 | 
			
		||||
  ctx->self->tid = ddsrt_thread_self ();
 | 
			
		||||
  ret = ctx->f (ctx->arg);
 | 
			
		||||
  ddsrt_free (ctx);
 | 
			
		||||
| 
						 | 
				
			
			@ -197,7 +199,7 @@ static int find_free_slot (const char *name)
 | 
			
		|||
  for (uint32_t i = 0; i < thread_states.nthreads; i++)
 | 
			
		||||
    if (thread_states.ts[i].state == THREAD_STATE_ZERO)
 | 
			
		||||
      return (int) i;
 | 
			
		||||
  DDS_FATAL("create_thread: %s: no free slot\n", name ? name : "(anon)");
 | 
			
		||||
  DDS_FATAL ("create_thread: %s: no free slot\n", name ? name : "(anon)");
 | 
			
		||||
  return -1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -274,12 +276,15 @@ static dds_return_t create_thread_int (struct thread_state1 **ts1, const struct
 | 
			
		|||
    if (!tprops->stack_size.isdefault)
 | 
			
		||||
      tattr.stackSize = tprops->stack_size.value;
 | 
			
		||||
  }
 | 
			
		||||
  DDS_TRACE("create_thread: %s: class %d priority %"PRId32" stack %"PRIu32"\n", name, (int) tattr.schedClass, tattr.schedPriority, tattr.stackSize);
 | 
			
		||||
  if (gv)
 | 
			
		||||
  {
 | 
			
		||||
    GVTRACE ("create_thread: %s: class %d priority %"PRId32" stack %"PRIu32"\n", name, (int) tattr.schedClass, tattr.schedPriority, tattr.stackSize);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (ddsrt_thread_create (&tid, name, &tattr, &create_thread_wrapper, ctxt) != DDS_RETCODE_OK)
 | 
			
		||||
  {
 | 
			
		||||
    (*ts1)->state = THREAD_STATE_ZERO;
 | 
			
		||||
    DDS_FATAL("create_thread: %s: ddsrt_thread_create failed\n", name);
 | 
			
		||||
    DDS_FATAL ("create_thread: %s: ddsrt_thread_create failed\n", name);
 | 
			
		||||
    goto fatal;
 | 
			
		||||
  }
 | 
			
		||||
  (*ts1)->extTid = tid; /* overwrite the temporary value with the correct external one */
 | 
			
		||||
| 
						 | 
				
			
			@ -336,10 +341,15 @@ void downgrade_main_thread (void)
 | 
			
		|||
  thread_states_init_static ();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void log_stack_traces (void)
 | 
			
		||||
void log_stack_traces (const struct ddsrt_log_cfg *logcfg, const struct q_globals *gv)
 | 
			
		||||
{
 | 
			
		||||
  for (uint32_t i = 0; i < thread_states.nthreads; i++)
 | 
			
		||||
    if (thread_states.ts[i].state != THREAD_STATE_ZERO)
 | 
			
		||||
      log_stacktrace (thread_states.ts[i].name, thread_states.ts[i].tid);
 | 
			
		||||
  {
 | 
			
		||||
    if (thread_states.ts[i].state != THREAD_STATE_ZERO &&
 | 
			
		||||
        (gv == NULL || ddsrt_atomic_ldvoidp (&thread_states.ts[i].gv) == gv))
 | 
			
		||||
    {
 | 
			
		||||
      log_stacktrace (logcfg, thread_states.ts[i].name, thread_states.ts[i].tid);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -177,12 +177,12 @@ struct nn_xmsg *writer_hbcontrol_create_heartbeat (struct writer *wr, const stru
 | 
			
		|||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  DDS_TRACE("writer_hbcontrol: wr "PGUIDFMT" ", PGUID (wr->e.guid));
 | 
			
		||||
  ETRACE (wr, "writer_hbcontrol: wr "PGUIDFMT" ", PGUID (wr->e.guid));
 | 
			
		||||
  if (prd_guid == NULL)
 | 
			
		||||
    DDS_TRACE("multicasting ");
 | 
			
		||||
    ETRACE (wr, "multicasting ");
 | 
			
		||||
  else
 | 
			
		||||
    DDS_TRACE("unicasting to prd "PGUIDFMT" ", PGUID (*prd_guid));
 | 
			
		||||
  DDS_TRACE("(rel-prd %d seq-eq-max %d seq %"PRId64" maxseq %"PRId64")\n",
 | 
			
		||||
    ETRACE (wr, "unicasting to prd "PGUIDFMT" ", PGUID (*prd_guid));
 | 
			
		||||
  ETRACE (wr, "(rel-prd %d seq-eq-max %d seq %"PRId64" maxseq %"PRId64")\n",
 | 
			
		||||
          wr->num_reliable_readers,
 | 
			
		||||
          ddsrt_avl_is_empty (&wr->readers) ? -1 : root_rdmatch (wr)->num_reliable_readers_where_seq_equals_max,
 | 
			
		||||
          wr->seq,
 | 
			
		||||
| 
						 | 
				
			
			@ -201,7 +201,7 @@ struct nn_xmsg *writer_hbcontrol_create_heartbeat (struct writer *wr, const stru
 | 
			
		|||
    struct proxy_reader *prd;
 | 
			
		||||
    if ((prd = ephash_lookup_proxy_reader_guid (gv->guid_hash, prd_guid)) == NULL)
 | 
			
		||||
    {
 | 
			
		||||
      DDS_TRACE("writer_hbcontrol: wr "PGUIDFMT" unknown prd "PGUIDFMT"\n", PGUID (wr->e.guid), PGUID (*prd_guid));
 | 
			
		||||
      ETRACE (wr, "writer_hbcontrol: wr "PGUIDFMT" unknown prd "PGUIDFMT"\n", PGUID (wr->e.guid), PGUID (*prd_guid));
 | 
			
		||||
      nn_xmsg_free (msg);
 | 
			
		||||
      return NULL;
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -301,7 +301,7 @@ struct nn_xmsg *writer_hbcontrol_piggyback (struct writer *wr, const struct whc_
 | 
			
		|||
 | 
			
		||||
  if (msg)
 | 
			
		||||
  {
 | 
			
		||||
    DDS_TRACE("heartbeat(wr "PGUIDFMT"%s) piggybacked, resched in %g s (min-ack %"PRId64"%s, avail-seq %"PRId64", xmit %"PRId64")\n",
 | 
			
		||||
    ETRACE (wr, "heartbeat(wr "PGUIDFMT"%s) piggybacked, resched in %g s (min-ack %"PRId64"%s, avail-seq %"PRId64", xmit %"PRId64")\n",
 | 
			
		||||
            PGUID (wr->e.guid),
 | 
			
		||||
            *hbansreq ? "" : " final",
 | 
			
		||||
            (hbc->tsched.v == T_NEVER) ? INFINITY : (double) (hbc->tsched.v - tnow.v) / 1e9,
 | 
			
		||||
| 
						 | 
				
			
			@ -621,9 +621,9 @@ dds_return_t create_fragment_message (struct writer *wr, seqno_t seq, const stru
 | 
			
		|||
  nn_xmsg_serdata (*pmsg, serdata, fragstart, fraglen);
 | 
			
		||||
  nn_xmsg_submsg_setnext (*pmsg, sm_marker);
 | 
			
		||||
#if 0
 | 
			
		||||
  DDS_TRACE("queue data%s "PGUIDFMT" #%lld/%u[%u..%u)\n",
 | 
			
		||||
          fragging ? "frag" : "", PGUID (wr->e.guid),
 | 
			
		||||
          seq, fragnum+1, fragstart, fragstart + fraglen);
 | 
			
		||||
  GVTRACE ("queue data%s "PGUIDFMT" #%lld/%u[%u..%u)\n",
 | 
			
		||||
           fragging ? "frag" : "", PGUID (wr->e.guid),
 | 
			
		||||
           seq, fragnum+1, fragstart, fragstart + fraglen);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
  return ret;
 | 
			
		||||
| 
						 | 
				
			
			@ -851,7 +851,7 @@ static int insert_sample_in_whc (struct writer *wr, seqno_t seq, struct nn_plist
 | 
			
		|||
 | 
			
		||||
  ASSERT_MUTEX_HELD (&wr->e.lock);
 | 
			
		||||
 | 
			
		||||
  if (dds_get_log_mask() & DDS_LC_TRACE)
 | 
			
		||||
  if (wr->e.gv->logconfig.c.mask & DDS_LC_TRACE)
 | 
			
		||||
  {
 | 
			
		||||
    char ppbuf[1024];
 | 
			
		||||
    int tmp;
 | 
			
		||||
| 
						 | 
				
			
			@ -859,10 +859,10 @@ static int insert_sample_in_whc (struct writer *wr, seqno_t seq, struct nn_plist
 | 
			
		|||
    const char *ttname = wr->topic ? wr->topic->type_name : "(null)";
 | 
			
		||||
    ppbuf[0] = '\0';
 | 
			
		||||
    tmp = sizeof (ppbuf) - 1;
 | 
			
		||||
    DDS_TRACE("write_sample "PGUIDFMT" #%"PRId64, PGUID (wr->e.guid), seq);
 | 
			
		||||
    ETRACE (wr, "write_sample "PGUIDFMT" #%"PRId64, PGUID (wr->e.guid), seq);
 | 
			
		||||
    if (plist != 0 && (plist->present & PP_COHERENT_SET))
 | 
			
		||||
      DDS_TRACE(" C#%"PRId64"", fromSN (plist->coherent_set_seqno));
 | 
			
		||||
    DDS_TRACE(": ST%"PRIu32" %s/%s:%s%s\n", serdata->statusinfo, tname, ttname, ppbuf, tmp < (int) sizeof (ppbuf) ? "" : " (trunc)");
 | 
			
		||||
      ETRACE (wr, " C#%"PRId64"", fromSN (plist->coherent_set_seqno));
 | 
			
		||||
    ETRACE (wr, ": ST%"PRIu32" %s/%s:%s%s\n", serdata->statusinfo, tname, ttname, ppbuf, tmp < (int) sizeof (ppbuf) ? "" : " (trunc)");
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  assert (wr->reliable || have_reliable_subs (wr) == 0);
 | 
			
		||||
| 
						 | 
				
			
			@ -948,7 +948,9 @@ static dds_return_t throttle_writer (struct thread_state1 * const ts1, struct nn
 | 
			
		|||
    assert (!is_builtin_entityid(wr->e.guid.entityid, NN_VENDORID_ECLIPSE));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  DDS_LOG(DDS_LC_THROTTLE, "writer "PGUIDFMT" waiting for whc to shrink below low-water mark (whc %"PRIuSIZE" low=%"PRIu32" high=%"PRIu32")\n", PGUID (wr->e.guid), whcst.unacked_bytes, wr->whc_low, wr->whc_high);
 | 
			
		||||
  GVLOG (DDS_LC_THROTTLE,
 | 
			
		||||
         "writer "PGUIDFMT" waiting for whc to shrink below low-water mark (whc %"PRIuSIZE" low=%"PRIu32" high=%"PRIu32")\n",
 | 
			
		||||
         PGUID (wr->e.guid), whcst.unacked_bytes, wr->whc_low, wr->whc_high);
 | 
			
		||||
  wr->throttling++;
 | 
			
		||||
  wr->throttle_count++;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -995,7 +997,9 @@ static dds_return_t throttle_writer (struct thread_state1 * const ts1, struct nn
 | 
			
		|||
    ddsrt_cond_broadcast (&wr->throttle_cond);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  DDS_LOG(DDS_LC_THROTTLE, "writer "PGUIDFMT" done waiting for whc to shrink below low-water mark (whc %"PRIuSIZE" low=%"PRIu32" high=%"PRIu32")\n", PGUID (wr->e.guid), whcst.unacked_bytes, wr->whc_low, wr->whc_high);
 | 
			
		||||
  GVLOG (DDS_LC_THROTTLE,
 | 
			
		||||
         "writer "PGUIDFMT" done waiting for whc to shrink below low-water mark (whc %"PRIuSIZE" low=%"PRIu32" high=%"PRIu32")\n",
 | 
			
		||||
         PGUID (wr->e.guid), whcst.unacked_bytes, wr->whc_low, wr->whc_high);
 | 
			
		||||
  return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1025,8 +1029,8 @@ static int write_sample_eot (struct thread_state1 * const ts1, struct nn_xpack *
 | 
			
		|||
  nn_mtime_t tnow;
 | 
			
		||||
 | 
			
		||||
  /* If GC not allowed, we must be sure to never block when writing.  That is only the case for (true, aggressive) KEEP_LAST writers, and also only if there is no limit to how much unacknowledged data the WHC may contain. */
 | 
			
		||||
  assert(gc_allowed || (wr->xqos->history.kind == DDS_HISTORY_KEEP_LAST && wr->whc_low == INT32_MAX));
 | 
			
		||||
  (void)gc_allowed;
 | 
			
		||||
  assert (gc_allowed || (wr->xqos->history.kind == DDS_HISTORY_KEEP_LAST && wr->whc_low == INT32_MAX));
 | 
			
		||||
  (void) gc_allowed;
 | 
			
		||||
 | 
			
		||||
  if (ddsi_serdata_size (serdata) > gv->config.max_sample_size)
 | 
			
		||||
  {
 | 
			
		||||
| 
						 | 
				
			
			@ -1036,10 +1040,10 @@ static int write_sample_eot (struct thread_state1 * const ts1, struct nn_xpack *
 | 
			
		|||
    const char *ttname = wr->topic ? wr->topic->type_name : "(null)";
 | 
			
		||||
    ppbuf[0] = '\0';
 | 
			
		||||
    tmp = sizeof (ppbuf) - 1;
 | 
			
		||||
    DDS_WARNING ("dropping oversize (%"PRIu32" > %"PRIu32") sample from local writer "PGUIDFMT" %s/%s:%s%s\n",
 | 
			
		||||
                 ddsi_serdata_size (serdata), gv->config.max_sample_size,
 | 
			
		||||
                 PGUID (wr->e.guid), tname, ttname, ppbuf,
 | 
			
		||||
                 tmp < (int) sizeof (ppbuf) ? "" : " (trunc)");
 | 
			
		||||
    GVWARNING ("dropping oversize (%"PRIu32" > %"PRIu32") sample from local writer "PGUIDFMT" %s/%s:%s%s\n",
 | 
			
		||||
               ddsi_serdata_size (serdata), gv->config.max_sample_size,
 | 
			
		||||
               PGUID (wr->e.guid), tname, ttname, ppbuf,
 | 
			
		||||
               tmp < (int) sizeof (ppbuf) ? "" : " (trunc)");
 | 
			
		||||
    r = DDS_RETCODE_BAD_PARAMETER;
 | 
			
		||||
    goto drop;
 | 
			
		||||
  }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -44,6 +44,8 @@
 | 
			
		|||
 | 
			
		||||
#include "dds/ddsi/sysdeps.h"
 | 
			
		||||
 | 
			
		||||
#define EVQTRACE(...) DDS_CTRACE (&evq->gv->logconfig, __VA_ARGS__)
 | 
			
		||||
 | 
			
		||||
/* This is absolute bottom for signed integers, where -x = x and yet x
 | 
			
		||||
   != 0 -- and note that it had better be 2's complement machine! */
 | 
			
		||||
#define TSCHED_DELETE ((int64_t) ((uint64_t) 1 << 63))
 | 
			
		||||
| 
						 | 
				
			
			@ -166,7 +168,7 @@ static int compare_xevent_tsched (const void *va, const void *vb)
 | 
			
		|||
static void update_rexmit_counts (struct xeventq *evq, struct xevent_nt *ev)
 | 
			
		||||
{
 | 
			
		||||
#if 0
 | 
			
		||||
  DDS_TRACE("ZZZ(%p,%"PRIuSIZE")", (void *) ev, ev->u.msg_rexmit.queued_rexmit_bytes);
 | 
			
		||||
  EVQTRACE ("ZZZ(%p,%"PRIuSIZE")", (void *) ev, ev->u.msg_rexmit.queued_rexmit_bytes);
 | 
			
		||||
#endif
 | 
			
		||||
  assert (ev->kind == XEVK_MSG_REXMIT);
 | 
			
		||||
  assert (ev->u.msg_rexmit.queued_rexmit_bytes <= evq->queued_rexmit_bytes);
 | 
			
		||||
| 
						 | 
				
			
			@ -176,7 +178,7 @@ static void update_rexmit_counts (struct xeventq *evq, struct xevent_nt *ev)
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
#if 0
 | 
			
		||||
static void trace_msg (const char *func, const struct nn_xmsg *m)
 | 
			
		||||
static void trace_msg (struct xeventq *evq, const char *func, const struct nn_xmsg *m)
 | 
			
		||||
{
 | 
			
		||||
  if (dds_get_log_mask() & DDS_LC_TRACE)
 | 
			
		||||
  {
 | 
			
		||||
| 
						 | 
				
			
			@ -184,11 +186,11 @@ static void trace_msg (const char *func, const struct nn_xmsg *m)
 | 
			
		|||
    seqno_t wrseq;
 | 
			
		||||
    nn_fragment_number_t wrfragid;
 | 
			
		||||
    nn_xmsg_guid_seq_fragid (m, &wrguid, &wrseq, &wrfragid);
 | 
			
		||||
    DDS_TRACE(" %s("PGUIDFMT"/%"PRId64"/%u)", func, PGUID (wrguid), wrseq, wrfragid);
 | 
			
		||||
    EVQTRACE(" %s("PGUIDFMT"/%"PRId64"/%u)", func, PGUID (wrguid), wrseq, wrfragid);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
#else
 | 
			
		||||
static void trace_msg (UNUSED_ARG (const char *func), UNUSED_ARG (const struct nn_xmsg *m))
 | 
			
		||||
static void trace_msg (UNUSED_ARG (struct xeventq *evq), UNUSED_ARG (const char *func), UNUSED_ARG (const struct nn_xmsg *m))
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			@ -196,21 +198,21 @@ static void trace_msg (UNUSED_ARG (const char *func), UNUSED_ARG (const struct n
 | 
			
		|||
static struct xevent_nt *lookup_msg (struct xeventq *evq, struct nn_xmsg *msg)
 | 
			
		||||
{
 | 
			
		||||
  assert (nn_xmsg_kind (msg) == NN_XMSG_KIND_DATA_REXMIT);
 | 
			
		||||
  trace_msg ("lookup-msg", msg);
 | 
			
		||||
  trace_msg (evq, "lookup-msg", msg);
 | 
			
		||||
  return ddsrt_avl_lookup (&msg_xevents_treedef, &evq->msg_xevents, msg);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void remember_msg (struct xeventq *evq, struct xevent_nt *ev)
 | 
			
		||||
{
 | 
			
		||||
  assert (ev->kind == XEVK_MSG_REXMIT);
 | 
			
		||||
  trace_msg ("remember-msg", ev->u.msg_rexmit.msg);
 | 
			
		||||
  trace_msg (evq, "remember-msg", ev->u.msg_rexmit.msg);
 | 
			
		||||
  ddsrt_avl_insert (&msg_xevents_treedef, &evq->msg_xevents, ev);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void forget_msg (struct xeventq *evq, struct xevent_nt *ev)
 | 
			
		||||
{
 | 
			
		||||
  assert (ev->kind == XEVK_MSG_REXMIT);
 | 
			
		||||
  trace_msg ("forget-msg", ev->u.msg_rexmit.msg);
 | 
			
		||||
  trace_msg (evq, "forget-msg", ev->u.msg_rexmit.msg);
 | 
			
		||||
  ddsrt_avl_delete (&msg_xevents_treedef, &evq->msg_xevents, ev);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -366,7 +368,7 @@ int resched_xevent_if_earlier (struct xevent *ev, nn_mtime_t tsched)
 | 
			
		|||
  return is_resched;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static struct xevent * qxev_common (struct xeventq *evq, nn_mtime_t tsched, enum xeventkind kind)
 | 
			
		||||
static struct xevent *qxev_common (struct xeventq *evq, nn_mtime_t tsched, enum xeventkind kind)
 | 
			
		||||
{
 | 
			
		||||
  /* qxev_common is the route by which all timed xevents are
 | 
			
		||||
     created. */
 | 
			
		||||
| 
						 | 
				
			
			@ -379,7 +381,7 @@ static struct xevent * qxev_common (struct xeventq *evq, nn_mtime_t tsched, enum
 | 
			
		|||
  if (tsched.v != T_NEVER && evq->gv->config.schedule_time_rounding != 0)
 | 
			
		||||
  {
 | 
			
		||||
    nn_mtime_t tsched_rounded = mtime_round_up (tsched, evq->gv->config.schedule_time_rounding);
 | 
			
		||||
    DDS_TRACE("rounded event scheduled for %"PRId64" to %"PRId64"\n", tsched.v, tsched_rounded.v);
 | 
			
		||||
    EVQTRACE ("rounded event scheduled for %"PRId64" to %"PRId64"\n", tsched.v, tsched_rounded.v);
 | 
			
		||||
    tsched = tsched_rounded;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -432,7 +434,7 @@ static void qxev_insert_nt (struct xevent_nt *ev)
 | 
			
		|||
  struct xeventq *evq = ev->evq;
 | 
			
		||||
  ASSERT_MUTEX_HELD (&evq->lock);
 | 
			
		||||
  add_to_non_timed_xmit_list (evq, ev);
 | 
			
		||||
  DDS_TRACE("non-timed queue now has %d items\n", compute_non_timed_xmit_list_size (evq));
 | 
			
		||||
  EVQTRACE ("non-timed queue now has %d items\n", compute_non_timed_xmit_list_size (evq));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int msg_xevents_cmp (const void *a, const void *b)
 | 
			
		||||
| 
						 | 
				
			
			@ -520,7 +522,7 @@ void xeventq_free (struct xeventq *evq)
 | 
			
		|||
      {
 | 
			
		||||
        union { void *v; void (*f) (struct xevent *ev, void *arg, nn_mtime_t tnow); } fp;
 | 
			
		||||
        fp.f = ev->u.callback.cb;
 | 
			
		||||
        DDS_WARNING("xeventq_free: callback %p did not schedule deletion as required, deleting event anyway\n", fp.v);
 | 
			
		||||
        DDS_CWARNING (&evq->gv->logconfig, "xeventq_free: callback %p did not schedule deletion as required, deleting event anyway\n", fp.v);
 | 
			
		||||
        delete_xevent (ev);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -587,8 +589,7 @@ static void handle_xevk_heartbeat (struct nn_xpack *xp, struct xevent *ev, nn_mt
 | 
			
		|||
 | 
			
		||||
  if ((wr = ephash_lookup_writer_guid (gv->guid_hash, &ev->u.heartbeat.wr_guid)) == NULL)
 | 
			
		||||
  {
 | 
			
		||||
    DDS_TRACE("heartbeat(wr "PGUIDFMT") writer gone\n",
 | 
			
		||||
            PGUID (ev->u.heartbeat.wr_guid));
 | 
			
		||||
    GVTRACE("heartbeat(wr "PGUIDFMT") writer gone\n", PGUID (ev->u.heartbeat.wr_guid));
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -614,14 +615,14 @@ static void handle_xevk_heartbeat (struct nn_xpack *xp, struct xevent *ev, nn_mt
 | 
			
		|||
    t_next.v = tnow.v + writer_hbcontrol_intv (wr, &whcst, tnow);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  DDS_TRACE("heartbeat(wr "PGUIDFMT"%s) %s, resched in %g s (min-ack %"PRId64"%s, avail-seq %"PRId64", xmit %"PRId64")\n",
 | 
			
		||||
          PGUID (wr->e.guid),
 | 
			
		||||
          hbansreq ? "" : " final",
 | 
			
		||||
          msg ? "sent" : "suppressed",
 | 
			
		||||
          (t_next.v == T_NEVER) ? INFINITY : (double)(t_next.v - tnow.v) / 1e9,
 | 
			
		||||
          ddsrt_avl_is_empty (&wr->readers) ? (seqno_t) -1 : ((struct wr_prd_match *) ddsrt_avl_root_non_empty (&wr_readers_treedef, &wr->readers))->min_seq,
 | 
			
		||||
          ddsrt_avl_is_empty (&wr->readers) || ((struct wr_prd_match *) ddsrt_avl_root_non_empty (&wr_readers_treedef, &wr->readers))->all_have_replied_to_hb ? "" : "!",
 | 
			
		||||
          whcst.max_seq, READ_SEQ_XMIT(wr));
 | 
			
		||||
  GVTRACE ("heartbeat(wr "PGUIDFMT"%s) %s, resched in %g s (min-ack %"PRId64"%s, avail-seq %"PRId64", xmit %"PRId64")\n",
 | 
			
		||||
           PGUID (wr->e.guid),
 | 
			
		||||
           hbansreq ? "" : " final",
 | 
			
		||||
           msg ? "sent" : "suppressed",
 | 
			
		||||
           (t_next.v == T_NEVER) ? INFINITY : (double)(t_next.v - tnow.v) / 1e9,
 | 
			
		||||
           ddsrt_avl_is_empty (&wr->readers) ? (seqno_t) -1 : ((struct wr_prd_match *) ddsrt_avl_root_non_empty (&wr_readers_treedef, &wr->readers))->min_seq,
 | 
			
		||||
           ddsrt_avl_is_empty (&wr->readers) || ((struct wr_prd_match *) ddsrt_avl_root_non_empty (&wr_readers_treedef, &wr->readers))->all_have_replied_to_hb ? "" : "!",
 | 
			
		||||
           whcst.max_seq, READ_SEQ_XMIT(wr));
 | 
			
		||||
  resched_xevent_if_earlier (ev, t_next);
 | 
			
		||||
  wr->hbcontrol.tsched = t_next;
 | 
			
		||||
  ddsrt_mutex_unlock (&wr->e.lock);
 | 
			
		||||
| 
						 | 
				
			
			@ -799,11 +800,11 @@ static void add_AckNack (struct nn_xmsg *msg, struct proxy_writer *pwr, struct p
 | 
			
		|||
    nn_xmsg_shrink (msg, sm_marker, ACKNACK_SIZE (an->readerSNState.numbits));
 | 
			
		||||
    nn_xmsg_submsg_setnext (msg, sm_marker);
 | 
			
		||||
 | 
			
		||||
    DDS_TRACE("acknack "PGUIDFMT" -> "PGUIDFMT": #%"PRId32":%"PRId64"/%"PRIu32":",
 | 
			
		||||
    ETRACE (pwr, "acknack "PGUIDFMT" -> "PGUIDFMT": #%"PRId32":%"PRId64"/%"PRIu32":",
 | 
			
		||||
            PGUID (rwn->rd_guid), PGUID (pwr->e.guid), rwn->count,
 | 
			
		||||
            base, an->readerSNState.numbits);
 | 
			
		||||
    for (uint32_t ui = 0; ui != an->readerSNState.numbits; ui++)
 | 
			
		||||
      DDS_TRACE("%c", nn_bitset_isset (numbits, an->bits, ui) ? '1' : '0');
 | 
			
		||||
      ETRACE (pwr, "%c", nn_bitset_isset (numbits, an->bits, ui) ? '1' : '0');
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (nackfrag_numbits > 0)
 | 
			
		||||
| 
						 | 
				
			
			@ -830,13 +831,13 @@ static void add_AckNack (struct nn_xmsg *msg, struct proxy_writer *pwr, struct p
 | 
			
		|||
      *countp = ++pwr->nackfragcount;
 | 
			
		||||
      nn_xmsg_submsg_setnext (msg, sm_marker);
 | 
			
		||||
 | 
			
		||||
      DDS_TRACE(" + nackfrag #%"PRId32":%"PRId64"/%u/%"PRIu32":", *countp, fromSN (nf->writerSN), nf->fragmentNumberState.bitmap_base, nf->fragmentNumberState.numbits);
 | 
			
		||||
      ETRACE (pwr, " + nackfrag #%"PRId32":%"PRId64"/%u/%"PRIu32":", *countp, fromSN (nf->writerSN), nf->fragmentNumberState.bitmap_base, nf->fragmentNumberState.numbits);
 | 
			
		||||
      for (uint32_t ui = 0; ui != nf->fragmentNumberState.numbits; ui++)
 | 
			
		||||
        DDS_TRACE("%c", nn_bitset_isset (nf->fragmentNumberState.numbits, nf->bits, ui) ? '1' : '0');
 | 
			
		||||
        ETRACE (pwr, "%c", nn_bitset_isset (nf->fragmentNumberState.numbits, nf->bits, ui) ? '1' : '0');
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  DDS_TRACE("\n");
 | 
			
		||||
  ETRACE (pwr, "\n");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void handle_xevk_acknack (UNUSED_ARG (struct nn_xpack *xp), struct xevent *ev, nn_mtime_t tnow)
 | 
			
		||||
| 
						 | 
				
			
			@ -896,13 +897,13 @@ static void handle_xevk_acknack (UNUSED_ARG (struct nn_xpack *xp), struct xevent
 | 
			
		|||
         eventually. */
 | 
			
		||||
      resched_xevent_if_earlier (ev, add_duration_to_mtime (tnow, gv->config.auto_resched_nack_delay));
 | 
			
		||||
    }
 | 
			
		||||
    DDS_TRACE("send acknack(rd "PGUIDFMT" -> pwr "PGUIDFMT")\n",
 | 
			
		||||
            PGUID (ev->u.acknack.rd_guid), PGUID (ev->u.acknack.pwr_guid));
 | 
			
		||||
    GVTRACE ("send acknack(rd "PGUIDFMT" -> pwr "PGUIDFMT")\n",
 | 
			
		||||
             PGUID (ev->u.acknack.rd_guid), PGUID (ev->u.acknack.pwr_guid));
 | 
			
		||||
  }
 | 
			
		||||
  else
 | 
			
		||||
  {
 | 
			
		||||
    DDS_TRACE("skip acknack(rd "PGUIDFMT" -> pwr "PGUIDFMT"): no address\n",
 | 
			
		||||
            PGUID (ev->u.acknack.rd_guid), PGUID (ev->u.acknack.pwr_guid));
 | 
			
		||||
    GVTRACE ("skip acknack(rd "PGUIDFMT" -> pwr "PGUIDFMT"): no address\n",
 | 
			
		||||
             PGUID (ev->u.acknack.rd_guid), PGUID (ev->u.acknack.pwr_guid));
 | 
			
		||||
    msg = NULL;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -985,8 +986,7 @@ static void handle_xevk_spdp (UNUSED_ARG (struct nn_xpack *xp), struct xevent *e
 | 
			
		|||
 | 
			
		||||
  if ((pp = ephash_lookup_participant_guid (gv->guid_hash, &ev->u.spdp.pp_guid)) == NULL)
 | 
			
		||||
  {
 | 
			
		||||
    DDS_TRACE("handle_xevk_spdp "PGUIDFMT" - unknown guid\n",
 | 
			
		||||
            PGUID (ev->u.spdp.pp_guid));
 | 
			
		||||
    GVTRACE ("handle_xevk_spdp "PGUIDFMT" - unknown guid\n", PGUID (ev->u.spdp.pp_guid));
 | 
			
		||||
    if (ev->u.spdp.directed)
 | 
			
		||||
      delete_xevent (ev);
 | 
			
		||||
    return;
 | 
			
		||||
| 
						 | 
				
			
			@ -994,8 +994,7 @@ static void handle_xevk_spdp (UNUSED_ARG (struct nn_xpack *xp), struct xevent *e
 | 
			
		|||
 | 
			
		||||
  if ((spdp_wr = get_builtin_writer (pp, NN_ENTITYID_SPDP_BUILTIN_PARTICIPANT_WRITER)) == NULL)
 | 
			
		||||
  {
 | 
			
		||||
    DDS_TRACE("handle_xevk_spdp "PGUIDFMT" - spdp writer of participant not found\n",
 | 
			
		||||
            PGUID (ev->u.spdp.pp_guid));
 | 
			
		||||
    GVTRACE ("handle_xevk_spdp "PGUIDFMT" - spdp writer of participant not found\n", PGUID (ev->u.spdp.pp_guid));
 | 
			
		||||
    if (ev->u.spdp.directed)
 | 
			
		||||
      delete_xevent (ev);
 | 
			
		||||
    return;
 | 
			
		||||
| 
						 | 
				
			
			@ -1016,7 +1015,7 @@ static void handle_xevk_spdp (UNUSED_ARG (struct nn_xpack *xp), struct xevent *e
 | 
			
		|||
    prd = ephash_lookup_proxy_reader_guid (gv->guid_hash, &guid);
 | 
			
		||||
    do_write = (prd != NULL);
 | 
			
		||||
    if (!do_write)
 | 
			
		||||
      DDS_TRACE("xmit spdp: no proxy reader "PGUIDFMT"\n", PGUID (guid));
 | 
			
		||||
      GVTRACE ("xmit spdp: no proxy reader "PGUIDFMT"\n", PGUID (guid));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (do_write && !resend_spdp_sample_by_guid_key (spdp_wr, &ev->u.spdp.pp_guid, prd))
 | 
			
		||||
| 
						 | 
				
			
			@ -1041,8 +1040,8 @@ static void handle_xevk_spdp (UNUSED_ARG (struct nn_xpack *xp), struct xevent *e
 | 
			
		|||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
      DDS_TRACE("xmit spdp: suppressing early spdp response from "PGUIDFMT" to %"PRIx32":%"PRIx32":%"PRIx32":%x\n",
 | 
			
		||||
                PGUID (pp->e.guid), PGUIDPREFIX (ev->u.spdp.dest_proxypp_guid_prefix), NN_ENTITYID_PARTICIPANT);
 | 
			
		||||
      GVTRACE ("xmit spdp: suppressing early spdp response from "PGUIDFMT" to %"PRIx32":%"PRIx32":%"PRIx32":%x\n",
 | 
			
		||||
               PGUID (pp->e.guid), PGUIDPREFIX (ev->u.spdp.dest_proxypp_guid_prefix), NN_ENTITYID_PARTICIPANT);
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
  }
 | 
			
		||||
| 
						 | 
				
			
			@ -1056,10 +1055,10 @@ static void handle_xevk_spdp (UNUSED_ARG (struct nn_xpack *xp), struct xevent *e
 | 
			
		|||
    else
 | 
			
		||||
    {
 | 
			
		||||
      nn_mtime_t tnext = add_duration_to_mtime (tnow, T_SECOND);
 | 
			
		||||
      DDS_TRACE("xmit spdp "PGUIDFMT" to %"PRIx32":%"PRIx32":%"PRIx32":%x (resched %gs)\n",
 | 
			
		||||
                PGUID (pp->e.guid),
 | 
			
		||||
                PGUIDPREFIX (ev->u.spdp.dest_proxypp_guid_prefix), NN_ENTITYID_SPDP_BUILTIN_PARTICIPANT_READER,
 | 
			
		||||
                (double)(tnext.v - tnow.v) / 1e9);
 | 
			
		||||
      GVTRACE ("xmit spdp "PGUIDFMT" to %"PRIx32":%"PRIx32":%"PRIx32":%x (resched %gs)\n",
 | 
			
		||||
               PGUID (pp->e.guid),
 | 
			
		||||
               PGUIDPREFIX (ev->u.spdp.dest_proxypp_guid_prefix), NN_ENTITYID_SPDP_BUILTIN_PARTICIPANT_READER,
 | 
			
		||||
               (double)(tnext.v - tnow.v) / 1e9);
 | 
			
		||||
      resched_xevent_if_earlier (ev, tnext);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
| 
						 | 
				
			
			@ -1083,10 +1082,10 @@ static void handle_xevk_spdp (UNUSED_ARG (struct nn_xpack *xp), struct xevent *e
 | 
			
		|||
      intv = gv->config.spdp_interval;
 | 
			
		||||
 | 
			
		||||
    tnext = add_duration_to_mtime (tnow, intv);
 | 
			
		||||
    DDS_TRACE("xmit spdp "PGUIDFMT" to %"PRIx32":%"PRIx32":%"PRIx32":%x (resched %gs)\n",
 | 
			
		||||
            PGUID (pp->e.guid),
 | 
			
		||||
            PGUIDPREFIX (ev->u.spdp.dest_proxypp_guid_prefix), NN_ENTITYID_SPDP_BUILTIN_PARTICIPANT_READER,
 | 
			
		||||
            (double)(tnext.v - tnow.v) / 1e9);
 | 
			
		||||
    GVTRACE ("xmit spdp "PGUIDFMT" to %"PRIx32":%"PRIx32":%"PRIx32":%x (resched %gs)\n",
 | 
			
		||||
             PGUID (pp->e.guid),
 | 
			
		||||
             PGUIDPREFIX (ev->u.spdp.dest_proxypp_guid_prefix), NN_ENTITYID_SPDP_BUILTIN_PARTICIPANT_READER,
 | 
			
		||||
             (double)(tnext.v - tnow.v) / 1e9);
 | 
			
		||||
    resched_xevent_if_earlier (ev, tnext);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1105,7 +1104,7 @@ static void write_pmd_message (struct thread_state1 * const ts1, struct nn_xpack
 | 
			
		|||
 | 
			
		||||
  if ((wr = get_builtin_writer (pp, NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_MESSAGE_WRITER)) == NULL)
 | 
			
		||||
  {
 | 
			
		||||
    DDS_TRACE("write_pmd_message("PGUIDFMT") - builtin pmd writer not found\n", PGUID (pp->e.guid));
 | 
			
		||||
    GVTRACE ("write_pmd_message("PGUIDFMT") - builtin pmd writer not found\n", PGUID (pp->e.guid));
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1156,7 +1155,7 @@ static void handle_xevk_pmd_update (struct thread_state1 * const ts1, struct nn_
 | 
			
		|||
  if (intv == T_NEVER)
 | 
			
		||||
  {
 | 
			
		||||
    tnext.v = T_NEVER;
 | 
			
		||||
    DDS_TRACE("resched pmd("PGUIDFMT"): never\n", PGUID (pp->e.guid));
 | 
			
		||||
    GVTRACE ("resched pmd("PGUIDFMT"): never\n", PGUID (pp->e.guid));
 | 
			
		||||
  }
 | 
			
		||||
  else
 | 
			
		||||
  {
 | 
			
		||||
| 
						 | 
				
			
			@ -1166,7 +1165,7 @@ static void handle_xevk_pmd_update (struct thread_state1 * const ts1, struct nn_
 | 
			
		|||
      tnext.v = tnow.v + intv - 2 * T_SECOND;
 | 
			
		||||
    else
 | 
			
		||||
      tnext.v = tnow.v + 4 * intv / 5;
 | 
			
		||||
    DDS_TRACE("resched pmd("PGUIDFMT"): %gs\n", PGUID (pp->e.guid), (double)(tnext.v - tnow.v) / 1e9);
 | 
			
		||||
    GVTRACE ("resched pmd("PGUIDFMT"): %gs\n", PGUID (pp->e.guid), (double)(tnext.v - tnow.v) / 1e9);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  resched_xevent_if_earlier (ev, tnext);
 | 
			
		||||
| 
						 | 
				
			
			@ -1177,7 +1176,7 @@ static void handle_xevk_delete_writer (UNUSED_ARG (struct nn_xpack *xp), struct
 | 
			
		|||
{
 | 
			
		||||
  /* don't worry if the writer is already gone by the time we get here. */
 | 
			
		||||
  struct q_globals * const gv = ev->evq->gv;
 | 
			
		||||
  DDS_TRACE("handle_xevk_delete_writer: "PGUIDFMT"\n", PGUID (ev->u.delete_writer.guid));
 | 
			
		||||
  GVTRACE ("handle_xevk_delete_writer: "PGUIDFMT"\n", PGUID (ev->u.delete_writer.guid));
 | 
			
		||||
  delete_writer_nolinger (gv, &ev->u.delete_writer.guid);
 | 
			
		||||
  delete_xevent (ev);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1333,7 +1332,7 @@ static uint32_t xevent_thread (struct xeventq * xevq)
 | 
			
		|||
  {
 | 
			
		||||
    nn_mtime_t tnow = now_mt ();
 | 
			
		||||
 | 
			
		||||
    LOG_THREAD_CPUTIME (next_thread_cputime);
 | 
			
		||||
    LOG_THREAD_CPUTIME (&xevq->gv->logconfig, next_thread_cputime);
 | 
			
		||||
 | 
			
		||||
    thread_state_awake_fixed_domain (ts1);
 | 
			
		||||
    handle_xevents (ts1, xevq, xp, tnow);
 | 
			
		||||
| 
						 | 
				
			
			@ -1401,7 +1400,7 @@ void qxev_prd_entityid (struct proxy_reader *prd, nn_guid_prefix_t *id)
 | 
			
		|||
    msg = nn_xmsg_new (gv->xmsgpool, id, sizeof (EntityId_t), NN_XMSG_KIND_CONTROL);
 | 
			
		||||
    if (nn_xmsg_setdstPRD (msg, prd) == 0)
 | 
			
		||||
    {
 | 
			
		||||
      DDS_TRACE("  qxev_prd_entityid (%"PRIx32":%"PRIx32":%"PRIx32")\n", PGUIDPREFIX (*id));
 | 
			
		||||
      GVTRACE ("  qxev_prd_entityid (%"PRIx32":%"PRIx32":%"PRIx32")\n", PGUIDPREFIX (*id));
 | 
			
		||||
      nn_xmsg_add_entityid (msg);
 | 
			
		||||
      ddsrt_mutex_lock (&gv->xevents->lock);
 | 
			
		||||
      ev = qxev_common_nt (gv->xevents, XEVK_ENTITYID);
 | 
			
		||||
| 
						 | 
				
			
			@ -1429,7 +1428,7 @@ void qxev_pwr_entityid (struct proxy_writer *pwr, nn_guid_prefix_t *id)
 | 
			
		|||
    msg = nn_xmsg_new (gv->xmsgpool, id, sizeof (EntityId_t), NN_XMSG_KIND_CONTROL);
 | 
			
		||||
    if (nn_xmsg_setdstPWR (msg, pwr) == 0)
 | 
			
		||||
    {
 | 
			
		||||
      DDS_TRACE("  qxev_pwr_entityid (%"PRIx32":%"PRIx32":%"PRIx32")\n", PGUIDPREFIX (*id));
 | 
			
		||||
      GVTRACE ("  qxev_pwr_entityid (%"PRIx32":%"PRIx32":%"PRIx32")\n", PGUIDPREFIX (*id));
 | 
			
		||||
      nn_xmsg_add_entityid (msg);
 | 
			
		||||
      ddsrt_mutex_lock (&pwr->evq->lock);
 | 
			
		||||
      ev = qxev_common_nt (pwr->evq, XEVK_ENTITYID);
 | 
			
		||||
| 
						 | 
				
			
			@ -1468,8 +1467,8 @@ int qxev_msg_rexmit_wrlock_held (struct xeventq *evq, struct nn_xmsg *msg, int f
 | 
			
		|||
    ddsrt_mutex_unlock (&evq->lock);
 | 
			
		||||
    nn_xmsg_free (msg);
 | 
			
		||||
#if 0
 | 
			
		||||
    DDS_TRACE(" qxev_msg_rexmit%s drop (sz %"PA_PRIuSIZE" qb %"PA_PRIuSIZE" qm %"PA_PRIuSIZE")", force ? "!" : "",
 | 
			
		||||
              msg_size, evq->queued_rexmit_bytes, evq->queued_rexmit_msgs);
 | 
			
		||||
    GVTRACE (" qxev_msg_rexmit%s drop (sz %"PA_PRIuSIZE" qb %"PA_PRIuSIZE" qm %"PA_PRIuSIZE")", force ? "!" : "",
 | 
			
		||||
             msg_size, evq->queued_rexmit_bytes, evq->queued_rexmit_msgs);
 | 
			
		||||
#endif
 | 
			
		||||
    return 0;
 | 
			
		||||
  }
 | 
			
		||||
| 
						 | 
				
			
			@ -1482,7 +1481,7 @@ int qxev_msg_rexmit_wrlock_held (struct xeventq *evq, struct nn_xmsg *msg, int f
 | 
			
		|||
    evq->queued_rexmit_msgs++;
 | 
			
		||||
    qxev_insert_nt (ev);
 | 
			
		||||
#if 0
 | 
			
		||||
    DDS_TRACE("AAA(%p,%"PA_PRIuSIZE")", (void *) ev, msg_size);
 | 
			
		||||
    GVTRACE ("AAA(%p,%"PA_PRIuSIZE")", (void *) ev, msg_size);
 | 
			
		||||
#endif
 | 
			
		||||
    ddsrt_mutex_unlock (&evq->lock);
 | 
			
		||||
    return 2;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -264,7 +264,6 @@ static void nn_xmsg_realfree_wrap (void *elem)
 | 
			
		|||
void nn_xmsgpool_free (struct nn_xmsgpool *pool)
 | 
			
		||||
{
 | 
			
		||||
  nn_freelist_fini (&pool->freelist, nn_xmsg_realfree_wrap);
 | 
			
		||||
  DDS_TRACE("xmsgpool_free(%p)\n", (void *)pool);
 | 
			
		||||
  ddsrt_free (pool);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -596,7 +595,7 @@ dds_return_t nn_xmsg_setdstPRD (struct nn_xmsg *m, const struct proxy_reader *pr
 | 
			
		|||
  }
 | 
			
		||||
  else
 | 
			
		||||
  {
 | 
			
		||||
    DDS_WARNING("nn_xmsg_setdstPRD: no address for "PGUIDFMT"", PGUID (prd->e.guid));
 | 
			
		||||
    DDS_CWARNING (&prd->e.gv->logconfig, "nn_xmsg_setdstPRD: no address for "PGUIDFMT"", PGUID (prd->e.guid));
 | 
			
		||||
    return DDS_RETCODE_PRECONDITION_NOT_MET;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -609,7 +608,7 @@ dds_return_t nn_xmsg_setdstPWR (struct nn_xmsg *m, const struct proxy_writer *pw
 | 
			
		|||
    nn_xmsg_setdst1 (m, &pwr->e.guid.prefix, &loc);
 | 
			
		||||
    return 0;
 | 
			
		||||
  }
 | 
			
		||||
  DDS_WARNING("nn_xmsg_setdstPRD: no address for "PGUIDFMT, PGUID (pwr->e.guid));
 | 
			
		||||
  DDS_CWARNING (&pwr->e.gv->logconfig, "nn_xmsg_setdstPRD: no address for "PGUIDFMT, PGUID (pwr->e.guid));
 | 
			
		||||
  return DDS_RETCODE_PRECONDITION_NOT_MET;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -665,8 +664,7 @@ int nn_xmsg_merge_rexmit_destinations_wrlock_held (struct q_globals *gv, struct
 | 
			
		|||
  assert (m->kindspecific.data.readerId_off != 0);
 | 
			
		||||
  assert (madd->kindspecific.data.readerId_off != 0);
 | 
			
		||||
 | 
			
		||||
  DDS_TRACE(" ("PGUIDFMT"#%"PRId64"/%u:",
 | 
			
		||||
            PGUID (m->kindspecific.data.wrguid), m->kindspecific.data.wrseq, m->kindspecific.data.wrfragid + 1);
 | 
			
		||||
  GVTRACE (" ("PGUIDFMT"#%"PRId64"/%u:", PGUID (m->kindspecific.data.wrguid), m->kindspecific.data.wrseq, m->kindspecific.data.wrfragid + 1);
 | 
			
		||||
 | 
			
		||||
  switch (m->dstmode)
 | 
			
		||||
  {
 | 
			
		||||
| 
						 | 
				
			
			@ -675,7 +673,7 @@ int nn_xmsg_merge_rexmit_destinations_wrlock_held (struct q_globals *gv, struct
 | 
			
		|||
      return 0;
 | 
			
		||||
 | 
			
		||||
    case NN_XMSG_DST_ALL:
 | 
			
		||||
      DDS_TRACE("*->*)");
 | 
			
		||||
      GVTRACE ("*->*)");
 | 
			
		||||
      return 1;
 | 
			
		||||
 | 
			
		||||
    case NN_XMSG_DST_ONE:
 | 
			
		||||
| 
						 | 
				
			
			@ -686,7 +684,7 @@ int nn_xmsg_merge_rexmit_destinations_wrlock_held (struct q_globals *gv, struct
 | 
			
		|||
          return 0;
 | 
			
		||||
 | 
			
		||||
        case NN_XMSG_DST_ALL:
 | 
			
		||||
          DDS_TRACE("1+*->*)");
 | 
			
		||||
          GVTRACE ("1+*->*)");
 | 
			
		||||
          clear_readerId (m);
 | 
			
		||||
          m->dstmode = NN_XMSG_DST_ALL;
 | 
			
		||||
          m->dstaddr.all.as = ref_addrset (madd->dstaddr.all.as);
 | 
			
		||||
| 
						 | 
				
			
			@ -705,12 +703,12 @@ int nn_xmsg_merge_rexmit_destinations_wrlock_held (struct q_globals *gv, struct
 | 
			
		|||
               can go and everyone's life will become easier! */
 | 
			
		||||
            if ((wr = ephash_lookup_writer_guid (gv->guid_hash, &m->kindspecific.data.wrguid)) == NULL)
 | 
			
		||||
            {
 | 
			
		||||
              DDS_TRACE("writer-dead)");
 | 
			
		||||
              GVTRACE ("writer-dead)");
 | 
			
		||||
              return 0;
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
              DDS_TRACE("1+1->*)");
 | 
			
		||||
              GVTRACE ("1+1->*)");
 | 
			
		||||
              clear_readerId (m);
 | 
			
		||||
              m->dstmode = NN_XMSG_DST_ALL;
 | 
			
		||||
              m->dstaddr.all.as = ref_addrset (wr->as);
 | 
			
		||||
| 
						 | 
				
			
			@ -720,12 +718,12 @@ int nn_xmsg_merge_rexmit_destinations_wrlock_held (struct q_globals *gv, struct
 | 
			
		|||
          }
 | 
			
		||||
          else if (readerId_compatible (m, madd))
 | 
			
		||||
          {
 | 
			
		||||
            DDS_TRACE("1+1->1)");
 | 
			
		||||
            GVTRACE ("1+1->1)");
 | 
			
		||||
            return 1;
 | 
			
		||||
          }
 | 
			
		||||
          else
 | 
			
		||||
          {
 | 
			
		||||
            DDS_TRACE("1+1->2)");
 | 
			
		||||
            GVTRACE ("1+1->2)");
 | 
			
		||||
            clear_readerId (m);
 | 
			
		||||
            return 1;
 | 
			
		||||
          }
 | 
			
		||||
| 
						 | 
				
			
			@ -896,7 +894,7 @@ static void nn_xmsg_chain_add (struct nn_xmsg_chain *chain, struct nn_xmsg *m)
 | 
			
		|||
 | 
			
		||||
#define NN_BW_LIMIT_MAX_BUFFER (-30 * T_MILLISECOND)
 | 
			
		||||
#define NN_BW_LIMIT_MIN_SLEEP (2 * T_MILLISECOND)
 | 
			
		||||
static void nn_bw_limit_sleep_if_needed(struct nn_bw_limiter* this, ssize_t size)
 | 
			
		||||
static void nn_bw_limit_sleep_if_needed (struct q_globals const * const gv, struct nn_bw_limiter *this, ssize_t size)
 | 
			
		||||
{
 | 
			
		||||
  if ( this->bandwidth > 0 ) {
 | 
			
		||||
    nn_mtime_t tnow = now_mt();
 | 
			
		||||
| 
						 | 
				
			
			@ -912,27 +910,27 @@ static void nn_bw_limit_sleep_if_needed(struct nn_bw_limiter* this, ssize_t size
 | 
			
		|||
    this->balance += (target_interval - actual_interval);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    DDS_TRACE(" <limiter(us):%"PRId64"",(target_interval - actual_interval)/1000);
 | 
			
		||||
    GVTRACE (" <limiter(us):%"PRId64"",(target_interval - actual_interval)/1000);
 | 
			
		||||
 | 
			
		||||
    if ( this->balance < NN_BW_LIMIT_MAX_BUFFER )
 | 
			
		||||
    {
 | 
			
		||||
      /* We're below the bandwidth limit, do not further accumulate  */
 | 
			
		||||
      this->balance = NN_BW_LIMIT_MAX_BUFFER;
 | 
			
		||||
      DDS_TRACE(":%"PRId64":max",this->balance/1000);
 | 
			
		||||
      GVTRACE (":%"PRId64":max",this->balance/1000);
 | 
			
		||||
    }
 | 
			
		||||
    else if ( this->balance > NN_BW_LIMIT_MIN_SLEEP )
 | 
			
		||||
    {
 | 
			
		||||
      /* We're over the bandwidth limit far enough, to warrent a sleep. */
 | 
			
		||||
      DDS_TRACE(":%"PRId64":sleep",this->balance/1000);
 | 
			
		||||
      GVTRACE (":%"PRId64":sleep",this->balance/1000);
 | 
			
		||||
      thread_state_blocked (lookup_thread_state ());
 | 
			
		||||
      dds_sleepfor (this->balance);
 | 
			
		||||
      thread_state_unblocked (lookup_thread_state ());
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
      DDS_TRACE(":%"PRId64"",this->balance/1000);
 | 
			
		||||
      GVTRACE (":%"PRId64"",this->balance/1000);
 | 
			
		||||
    }
 | 
			
		||||
    DDS_TRACE(">");
 | 
			
		||||
    GVTRACE (">");
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1039,22 +1037,23 @@ void nn_xpack_free (struct nn_xpack *xp)
 | 
			
		|||
 | 
			
		||||
static ssize_t nn_xpack_send1 (const nn_locator_t *loc, void * varg)
 | 
			
		||||
{
 | 
			
		||||
  struct nn_xpack * xp = varg;
 | 
			
		||||
  struct nn_xpack *xp = varg;
 | 
			
		||||
  struct q_globals const * const gv = xp->gv;
 | 
			
		||||
  ssize_t nbytes = 0;
 | 
			
		||||
 | 
			
		||||
  if (dds_get_log_mask() & DDS_LC_TRACE)
 | 
			
		||||
  if (gv->logconfig.c.mask & DDS_LC_TRACE)
 | 
			
		||||
  {
 | 
			
		||||
    char buf[DDSI_LOCSTRLEN];
 | 
			
		||||
    DDS_TRACE(" %s", ddsi_locator_to_string (xp->gv, buf, sizeof(buf), loc));
 | 
			
		||||
    GVTRACE (" %s", ddsi_locator_to_string (gv, buf, sizeof(buf), loc));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (xp->gv->config.xmit_lossiness > 0)
 | 
			
		||||
  if (gv->config.xmit_lossiness > 0)
 | 
			
		||||
  {
 | 
			
		||||
    /* We drop APPROXIMATELY a fraction of xmit_lossiness * 10**(-3)
 | 
			
		||||
       of all packets to be sent */
 | 
			
		||||
    if ((ddsrt_random () % 1000) < (uint32_t) xp->gv->config.xmit_lossiness)
 | 
			
		||||
    if ((ddsrt_random () % 1000) < (uint32_t) gv->config.xmit_lossiness)
 | 
			
		||||
    {
 | 
			
		||||
      DDS_TRACE("(dropped)");
 | 
			
		||||
      GVTRACE ("(dropped)");
 | 
			
		||||
      xp->call_flags = 0;
 | 
			
		||||
      return 0;
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -1070,7 +1069,7 @@ static ssize_t nn_xpack_send1 (const nn_locator_t *loc, void * varg)
 | 
			
		|||
  else
 | 
			
		||||
#endif
 | 
			
		||||
  {
 | 
			
		||||
    if (!xp->gv->mute)
 | 
			
		||||
    if (!gv->mute)
 | 
			
		||||
    {
 | 
			
		||||
      nbytes = ddsi_conn_write (xp->conn, loc, xp->niov, xp->iov, xp->call_flags);
 | 
			
		||||
#ifndef NDEBUG
 | 
			
		||||
| 
						 | 
				
			
			@ -1085,7 +1084,7 @@ static ssize_t nn_xpack_send1 (const nn_locator_t *loc, void * varg)
 | 
			
		|||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
      DDS_TRACE("(dropped)");
 | 
			
		||||
      GVTRACE ("(dropped)");
 | 
			
		||||
      nbytes = (ssize_t) xp->msg_len.length;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
| 
						 | 
				
			
			@ -1097,7 +1096,7 @@ static ssize_t nn_xpack_send1 (const nn_locator_t *loc, void * varg)
 | 
			
		|||
#ifdef DDSI_INCLUDE_BANDWIDTH_LIMITING
 | 
			
		||||
  if (nbytes > 0)
 | 
			
		||||
  {
 | 
			
		||||
    nn_bw_limit_sleep_if_needed (&xp->limiter, nbytes);
 | 
			
		||||
    nn_bw_limit_sleep_if_needed (gv, &xp->limiter, nbytes);
 | 
			
		||||
  }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1134,8 +1133,9 @@ static void nn_xpack_send1_threaded (const nn_locator_t *loc, void * varg)
 | 
			
		|||
  ddsrt_thread_pool_submit (arg->xp->gv->thread_pool, nn_xpack_send1_thread, arg);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void nn_xpack_send_real (struct nn_xpack * xp)
 | 
			
		||||
static void nn_xpack_send_real (struct nn_xpack *xp)
 | 
			
		||||
{
 | 
			
		||||
  struct q_globals const * const gv = xp->gv;
 | 
			
		||||
  size_t calls;
 | 
			
		||||
 | 
			
		||||
  assert (xp->niov <= NN_XMSG_MAX_MESSAGE_IOVECS);
 | 
			
		||||
| 
						 | 
				
			
			@ -1147,17 +1147,17 @@ static void nn_xpack_send_real (struct nn_xpack * xp)
 | 
			
		|||
 | 
			
		||||
  assert (xp->dstmode != NN_XMSG_DST_UNSET);
 | 
			
		||||
 | 
			
		||||
  if (dds_get_log_mask() & DDS_LC_TRACE)
 | 
			
		||||
  if (gv->logconfig.c.mask & DDS_LC_TRACE)
 | 
			
		||||
  {
 | 
			
		||||
    int i;
 | 
			
		||||
    DDS_TRACE("nn_xpack_send %"PRIu32":", xp->msg_len.length);
 | 
			
		||||
    GVTRACE ("nn_xpack_send %"PRIu32":", xp->msg_len.length);
 | 
			
		||||
    for (i = 0; i < (int) xp->niov; i++)
 | 
			
		||||
    {
 | 
			
		||||
      DDS_TRACE(" %p:%lu", (void *) xp->iov[i].iov_base, (unsigned long) xp->iov[i].iov_len);
 | 
			
		||||
      GVTRACE (" %p:%lu", (void *) xp->iov[i].iov_base, (unsigned long) xp->iov[i].iov_len);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  DDS_TRACE(" [");
 | 
			
		||||
  GVTRACE (" [");
 | 
			
		||||
  if (xp->dstmode == NN_XMSG_DST_ONE)
 | 
			
		||||
  {
 | 
			
		||||
    calls = 1;
 | 
			
		||||
| 
						 | 
				
			
			@ -1200,10 +1200,10 @@ static void nn_xpack_send_real (struct nn_xpack * xp)
 | 
			
		|||
      unref_addrset (xp->dstaddr.all.as_group);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  DDS_TRACE(" ]\n");
 | 
			
		||||
  GVTRACE (" ]\n");
 | 
			
		||||
  if (calls)
 | 
			
		||||
  {
 | 
			
		||||
    DDS_LOG(DDS_LC_TRAFFIC, "traffic-xmit (%lu) %"PRIu32"\n", (unsigned long) calls, xp->msg_len.length);
 | 
			
		||||
    GVLOG (DDS_LC_TRAFFIC, "traffic-xmit (%lu) %"PRIu32"\n", (unsigned long) calls, xp->msg_len.length);
 | 
			
		||||
  }
 | 
			
		||||
  nn_xmsg_chain_release (xp->gv, &xp->included_msgs);
 | 
			
		||||
  nn_xpack_reinit (xp);
 | 
			
		||||
| 
						 | 
				
			
			@ -1393,7 +1393,7 @@ static int guid_prefix_eq (const nn_guid_prefix_t *a, const nn_guid_prefix_t *b)
 | 
			
		|||
int nn_xpack_addmsg (struct nn_xpack *xp, struct nn_xmsg *m, const uint32_t flags)
 | 
			
		||||
{
 | 
			
		||||
  /* Returns > 0 if pack got sent out before adding m */
 | 
			
		||||
 | 
			
		||||
  struct q_globals const * const gv = xp->gv;
 | 
			
		||||
  static InfoDST_t static_zero_dst = {
 | 
			
		||||
    { SMID_INFO_DST, (DDSRT_ENDIAN == DDSRT_LITTLE_ENDIAN ? SMFLAG_ENDIANNESS : 0), sizeof (nn_guid_prefix_t) },
 | 
			
		||||
    { { 0,0,0,0, 0,0,0,0, 0,0,0,0 } }
 | 
			
		||||
| 
						 | 
				
			
			@ -1437,22 +1437,22 @@ int nn_xpack_addmsg (struct nn_xpack *xp, struct nn_xmsg *m, const uint32_t flag
 | 
			
		|||
     But do make sure we can't run out of iovecs. */
 | 
			
		||||
  assert (niov + NN_XMSG_MAX_SUBMESSAGE_IOVECS <= NN_XMSG_MAX_MESSAGE_IOVECS);
 | 
			
		||||
 | 
			
		||||
  DDS_TRACE("xpack_addmsg %p %p %"PRIu32"(", (void *) xp, (void *) m, flags);
 | 
			
		||||
  GVTRACE ("xpack_addmsg %p %p %"PRIu32"(", (void *) xp, (void *) m, flags);
 | 
			
		||||
  switch (m->kind)
 | 
			
		||||
  {
 | 
			
		||||
    case NN_XMSG_KIND_CONTROL:
 | 
			
		||||
      DDS_TRACE("control");
 | 
			
		||||
      GVTRACE ("control");
 | 
			
		||||
      break;
 | 
			
		||||
    case NN_XMSG_KIND_DATA:
 | 
			
		||||
    case NN_XMSG_KIND_DATA_REXMIT:
 | 
			
		||||
      DDS_TRACE("%s("PGUIDFMT":#%"PRId64"/%u)",
 | 
			
		||||
              (m->kind == NN_XMSG_KIND_DATA) ? "data" : "rexmit",
 | 
			
		||||
              PGUID (m->kindspecific.data.wrguid),
 | 
			
		||||
              m->kindspecific.data.wrseq,
 | 
			
		||||
              m->kindspecific.data.wrfragid + 1);
 | 
			
		||||
      GVTRACE ("%s("PGUIDFMT":#%"PRId64"/%u)",
 | 
			
		||||
               (m->kind == NN_XMSG_KIND_DATA) ? "data" : "rexmit",
 | 
			
		||||
               PGUID (m->kindspecific.data.wrguid),
 | 
			
		||||
               m->kindspecific.data.wrseq,
 | 
			
		||||
               m->kindspecific.data.wrfragid + 1);
 | 
			
		||||
      break;
 | 
			
		||||
  }
 | 
			
		||||
  DDS_TRACE("): niov %d sz %"PRIuSIZE, (int) niov, sz);
 | 
			
		||||
  GVTRACE ("): niov %d sz %"PRIuSIZE, (int) niov, sz);
 | 
			
		||||
 | 
			
		||||
  /* If a fresh xp has been provided, add an RTPS header */
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1580,7 +1580,8 @@ int nn_xpack_addmsg (struct nn_xpack *xp, struct nn_xmsg *m, const uint32_t flag
 | 
			
		|||
 | 
			
		||||
  if (xpo_niov > 0 && sz > xp->gv->config.max_msg_size)
 | 
			
		||||
  {
 | 
			
		||||
    DDS_TRACE(" => now niov %d sz %"PRIuSIZE" > max_msg_size %"PRIu32", nn_xpack_send niov %d sz %"PRIu32" now\n", (int) niov, sz, xp->gv->config.max_msg_size, (int) xpo_niov, xpo_sz);
 | 
			
		||||
    GVTRACE (" => now niov %d sz %"PRIuSIZE" > max_msg_size %"PRIu32", nn_xpack_send niov %d sz %"PRIu32" now\n",
 | 
			
		||||
             (int) niov, sz, gv->config.max_msg_size, (int) xpo_niov, xpo_sz);
 | 
			
		||||
    xp->msg_len.length = xpo_sz;
 | 
			
		||||
    xp->niov = xpo_niov;
 | 
			
		||||
    nn_xpack_send (xp, false);
 | 
			
		||||
| 
						 | 
				
			
			@ -1590,7 +1591,7 @@ int nn_xpack_addmsg (struct nn_xpack *xp, struct nn_xmsg *m, const uint32_t flag
 | 
			
		|||
  {
 | 
			
		||||
    xp->call_flags = flags;
 | 
			
		||||
    nn_xmsg_chain_add (&xp->included_msgs, m);
 | 
			
		||||
    DDS_TRACE(" => now niov %d sz %"PRIuSIZE"\n", (int) niov, sz);
 | 
			
		||||
    GVTRACE (" => now niov %d sz %"PRIuSIZE"\n", (int) niov, sz);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return result;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -19,7 +19,7 @@
 | 
			
		|||
#include "dds/ddsi/sysdeps.h"
 | 
			
		||||
 | 
			
		||||
#if DDSRT_WITH_FREERTOS || !(defined __APPLE__ || defined __linux) || (__GNUC__ > 0 && (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) < 40100)
 | 
			
		||||
void log_stacktrace (const char *name, ddsrt_thread_t tid)
 | 
			
		||||
void log_stacktrace (const struct ddsrt_log_cfg *logcfg, const char *name, ddsrt_thread_t tid)
 | 
			
		||||
{
 | 
			
		||||
  DDSRT_UNUSED_ARG (name);
 | 
			
		||||
  DDSRT_UNUSED_ARG (tid);
 | 
			
		||||
| 
						 | 
				
			
			@ -44,13 +44,13 @@ static void log_stacktrace_sigh (int sig __attribute__ ((unused)))
 | 
			
		|||
  errno = e;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void log_stacktrace (const char *name, ddsrt_thread_t tid)
 | 
			
		||||
void log_stacktrace (const struct ddsrt_log_cfg *logcfg, const char *name, ddsrt_thread_t tid)
 | 
			
		||||
{
 | 
			
		||||
  const dds_time_t d = 1000000;
 | 
			
		||||
  struct sigaction act, oact;
 | 
			
		||||
  char **strs;
 | 
			
		||||
  int i;
 | 
			
		||||
  DDS_LOG(~DDS_LC_FATAL, "-- stack trace of %s requested --\n", name);
 | 
			
		||||
  DDS_CLOG (~DDS_LC_FATAL, logcfg, "-- stack trace of %s requested --\n", name);
 | 
			
		||||
  act.sa_handler = log_stacktrace_sigh;
 | 
			
		||||
  act.sa_flags = 0;
 | 
			
		||||
  sigfillset (&act.sa_mask);
 | 
			
		||||
| 
						 | 
				
			
			@ -62,15 +62,15 @@ void log_stacktrace (const char *name, ddsrt_thread_t tid)
 | 
			
		|||
    dds_sleepfor (d);
 | 
			
		||||
  sigaction (SIGXCPU, &oact, NULL);
 | 
			
		||||
  if (pthread_kill (tid.v, 0) != 0)
 | 
			
		||||
    DDS_LOG(~DDS_LC_FATAL, "-- thread exited --\n");
 | 
			
		||||
    DDS_CLOG (~DDS_LC_FATAL, logcfg, "-- thread exited --\n");
 | 
			
		||||
  else
 | 
			
		||||
  {
 | 
			
		||||
    DDS_LOG(~DDS_LC_FATAL, "-- stack trace follows --\n");
 | 
			
		||||
    DDS_CLOG (~DDS_LC_FATAL, logcfg, "-- stack trace follows --\n");
 | 
			
		||||
    strs = backtrace_symbols (log_stacktrace_stk.stk, log_stacktrace_stk.depth);
 | 
			
		||||
    for (i = 0; i < log_stacktrace_stk.depth; i++)
 | 
			
		||||
      DDS_LOG(~DDS_LC_FATAL, "%s\n", strs[i]);
 | 
			
		||||
      DDS_CLOG (~DDS_LC_FATAL, logcfg, "%s\n", strs[i]);
 | 
			
		||||
    free (strs);
 | 
			
		||||
    DDS_LOG(~DDS_LC_FATAL, "-- end of stack trace --\n");
 | 
			
		||||
    DDS_CLOG (~DDS_LC_FATAL, logcfg, "-- end of stack trace --\n");
 | 
			
		||||
  }
 | 
			
		||||
  ddsrt_atomic_st32 (&log_stacktrace_flag, 0);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -163,7 +163,7 @@ static void fwr (struct proxy_writer *wr)
 | 
			
		|||
  free (wr);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static struct dds_rhc *mkrhc (const struct q_globals *gv, dds_reader *rd, dds_history_kind_t hk, int32_t hdepth, dds_destination_order_kind_t dok)
 | 
			
		||||
static struct dds_rhc *mkrhc (struct q_globals *gv, dds_reader *rd, dds_history_kind_t hk, int32_t hdepth, dds_destination_order_kind_t dok)
 | 
			
		||||
{
 | 
			
		||||
  struct dds_rhc *rhc;
 | 
			
		||||
  dds_qos_t rqos;
 | 
			
		||||
| 
						 | 
				
			
			@ -174,7 +174,7 @@ static struct dds_rhc *mkrhc (const struct q_globals *gv, dds_reader *rd, dds_hi
 | 
			
		|||
  rqos.destination_order.kind = dok;
 | 
			
		||||
  nn_xqos_mergein_missing (&rqos, &gv->default_xqos_rd, ~(uint64_t)0);
 | 
			
		||||
  thread_state_awake_domain_ok (lookup_thread_state ());
 | 
			
		||||
  rhc = dds_rhc_default_new_xchecks (rd, gv->m_tkmap, mdtopic, true);
 | 
			
		||||
  rhc = dds_rhc_default_new_xchecks (rd, gv, mdtopic, true);
 | 
			
		||||
  dds_rhc_set_qos(rhc, &rqos);
 | 
			
		||||
  thread_state_asleep (lookup_thread_state ());
 | 
			
		||||
  return rhc;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue